插入数据库时​​没有这样的表异常

时间:2017-02-14 14:35:37

标签: android sqlite junit4

我正在开发一个简单的空气质量控制应用程序。我需要使用SQLite存储空气质量测量值。我创建了扩展SQLiteOpenHelper类的db helper类。它应该创建一个表measurements

public class SmogDbHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;

    public static final String DATABASE_NAME = "smog.db";

    interface Tables {
        String MEASUREMENT = "measurement";
    }

    interface Triggers {
        String ON_MEASUREMENT_INSERTED = "on_measurement_inserted";
    }

    public SmogDbHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        final String SQL_CREATE_TABLE_MEASUREMENT =
                "CREATE TABLE " + Tables.MEASUREMENT + " (" + MeasurementEntry._ID +
                " INTEGER PRIMARY KEY, " +
                MeasurementEntry.COLUMN_LONGITUDE + " REAL NOT NULL, " +
                MeasurementEntry.COLUMN_LATITUDE + " REAL NOT NULL, " +
                MeasurementEntry.COLUMN_FROM_DATE_TIME + " INTEGER NOT NULL, " +
                MeasurementEntry.COLUMN_TILL_DATE_TIME + " INTEGER, " +
                MeasurementEntry.COLUMN_PM_1 + " REAL NOT NULL, " +
                MeasurementEntry.COLUMN_PM_25 + " REAL NOT NULL, " +
                MeasurementEntry.COLUMN_PM_10 + " REAL NOT NULL, " +
                MeasurementEntry.COLUMN_POLUTION_LEVEL + " INTEGER NOT NULL, " +
                MeasurementEntry.COLUMN_AIR_QUALITY_INDEX + " REAL NOT NULL, " +
                MeasurementEntry.COLUMN_SOURCE + " TEXT NOT NULL" +
                ");";

        final String SQL_CREATE_ON_MEASUREMENT_INSERTED_TRIGGER = "CREATE TRIGGER " + Triggers.ON_MEASUREMENT_INSERTED +
                " AFTER INSERT ON " + Tables.MEASUREMENT +
                " BEGIN " +
                "DELETE FROM LOG WHERE " + MeasurementEntry.COLUMN_FROM_DATE_TIME + " < " +
                "(strftime('%s', 'now') - 604800);\n" +
                " END;";

        db.execSQL(SQL_CREATE_TABLE_MEASUREMENT);
        db.execSQL(SQL_CREATE_ON_MEASUREMENT_INSERTED_TRIGGER);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + Tables.MEASUREMENT);
        db.execSQL("DROP TRIGGER IF EXISTS " + Triggers.ON_MEASUREMENT_INSERTED);
    }
}

使用以下单元测试进行测试。

@RunWith(AndroidJUnit4.class)
@LargeTest
public class TestDb {

    private static final String LOG_TAG = "TestDb";
    private SmogDbHelper smogDbHelper;
    private SQLiteDatabase db;

    // remove old database if present before starting tests
    @Before
    public void setUp() throws Exception {
        getTargetContext().deleteDatabase(SmogDbHelper.DATABASE_NAME);
        smogDbHelper = new SmogDbHelper(getTargetContext());
        db = smogDbHelper.getWritableDatabase();
    }

    @After
    public void tearDown() throws Exception {
        db.close();
    }

    @Test
    public void testTableCreation() {

        Assert.assertEquals(true, db.isOpen());

        // hash set of all tables we are looking for in the db
        final HashSet<String> tableNameHashSet = new HashSet<String>();
        tableNameHashSet.add(SmogContract.MeasurementEntry.TABLE_NAME);

        Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='table'", null);

        Assert.assertTrue("Error: This means that the database has not been created correctly",
                c.moveToFirst());

        // remove all table names from hash map which are in db.
        do {
            String tableName = c.getString(0);
            Log.v(LOG_TAG, tableName);
            tableNameHashSet.remove(tableName);
        } while (c.moveToNext());

        c.close();
        // if this fails not all tables have been created correctly
        Assert.assertTrue("Error: Your database is missing " + tableNameHashSet.size()
                + " tables.", tableNameHashSet.isEmpty());

        c = db.rawQuery("PRAGMA table_info(" + SmogContract.MeasurementEntry.TABLE_NAME + ")",
                null);

        Assert.assertTrue("Error: Unable to query the database for table information.",
                c.moveToFirst());

        // all columns we want to look for in MeasurementEntry
        final HashSet<String> measurementColumnHashSet = new HashSet<String>();
        measurementColumnHashSet.add(SmogContract.MeasurementEntry._ID);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_AIR_QUALITY_INDEX);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_FROM_DATE_TIME);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_TILL_DATE_TIME);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_LATITUDE);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_LONGITUDE);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_PM_1);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_PM_25);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_PM_10);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_SOURCE);
        measurementColumnHashSet.add(SmogContract.MeasurementEntry.COLUMN_POLUTION_LEVEL);

        int columnNameIndex = c.getColumnIndex("name");
        do {
            String columnName = c.getString(columnNameIndex);
            Log.v(LOG_TAG, columnName);
            measurementColumnHashSet.remove(columnName);
        } while (c.moveToNext());

        Assert.assertTrue("Error: The database doesn't contain all of the required location entry columns",
                measurementColumnHashSet.isEmpty());

        c.close();
    }

    @Test
    public void testMeasurementTable() {

        ContentValues measurementValues = TestUtilities.createMeasurementValues();
        long measurementRowId = db.insert(SmogContract.MeasurementEntry.TABLE_NAME,
                null, measurementValues);
        Assert.assertTrue(measurementRowId != -1);

        Cursor measurementCursor = db.query(
                SmogContract.MeasurementEntry.TABLE_NAME,
                null, null, null, null, null, null
        );
        Assert.assertTrue("Error: No Records returned from location query",
                measurementCursor.moveToFirst());

        measurementCursor.close();
    }

}

虽然运行插入和查询测试时表创建的测试工作正常,但我得到以下异常。

android.database.sqlite.SQLiteException: no such table: main.LOG (code 1): , while compiling: INSERT INTO measurement(pm_25,from_date_time,pm_10,polution_level,source,till_date_time,air_quality_index,longitude,latitude,pm_1) VALUES (?,?,?,?,?,?,?,?,?,?)

我对可能导致这种情况的想法不以为然。任何帮助或建议一如既往地非常感谢。

1 个答案:

答案 0 :(得分:1)

触发器说:

DELETE FROM LOG ...

但是没有这样的表格。

您可能想要从同一个表中删除。