-2
간단한 대기 품질 제어 응용 프로그램에서 작업하고 있습니다. SQLite를 사용하여 대기 질 측정 값을 저장해야합니다. SQLiteOpenHelper 클래스를 확장 한 db 헬퍼 클래스를 만들었습니다. 단일 테이블 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 (?,?,?,?,?,?,?,?,?,?)
나는이 문제의 원인에 관한 아이디어가 없습니다. 어떤 도움이나 제안도 늘 그렇듯이 크게 감사합니다.
DELETE FROM LOG ...
을하지만 그런 테이블이 없습니다 :
고맙습니다. 테이블 이름을 변경하고 트리거에서 코딩 된 이름을 잊어 버렸습니다. – Lukasz