summaryrefslogtreecommitdiffstats
path: root/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java')
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java871
1 files changed, 871 insertions, 0 deletions
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
new file mode 100644
index 0000000..b004c93
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
@@ -0,0 +1,871 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.unit_tests;
+
+import android.content.ContentValues;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.CharArrayBuffer;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteStatement;
+import android.os.Handler;
+import android.os.Parcel;
+import android.test.PerformanceTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.text.Collator;
+import java.util.Arrays;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_COLUMNNAME_INDEX;
+import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_DEFAULT_INDEX;
+
+public class DatabaseGeneralTest extends TestCase implements PerformanceTestCase {
+
+ private static final String sString1 = "this is a test";
+ private static final String sString2 = "and yet another test";
+ private static final String sString3 = "this string is a little longer, but still a test";
+ private static final String PHONE_NUMBER = "16175551212";
+
+ private static final int CURRENT_DATABASE_VERSION = 42;
+ private SQLiteDatabase mDatabase;
+ private File mDatabaseFile;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDatabaseFile = new File("/sqlite_stmt_journals", "database_test.db");
+ if (mDatabaseFile.exists()) {
+ mDatabaseFile.delete();
+ }
+ mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
+ assertNotNull(mDatabase);
+ mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mDatabase.close();
+ mDatabaseFile.delete();
+ super.tearDown();
+ }
+
+ public boolean isPerformanceOnly() {
+ return false;
+ }
+
+ // These test can only be run once.
+ public int startPerformance(Intermediates intermediates) {
+ return 1;
+ }
+
+ private void populateDefaultTable() {
+ mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
+
+ mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');");
+ mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');");
+ mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
+ }
+
+ @MediumTest
+ public void testVersion() throws Exception {
+ assertEquals(CURRENT_DATABASE_VERSION, mDatabase.getVersion());
+ mDatabase.setVersion(11);
+ assertEquals(11, mDatabase.getVersion());
+ }
+
+ @MediumTest
+ public void testUpdate() throws Exception {
+ populateDefaultTable();
+
+ ContentValues values = new ContentValues(1);
+ values.put("data", "this is an updated test");
+ assertEquals(1, mDatabase.update("test", values, "_id=1", null));
+ Cursor c = mDatabase.query("test", null, "_id=1", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ String value = c.getString(c.getColumnIndexOrThrow("data"));
+ assertEquals("this is an updated test", value);
+ }
+
+ @MediumTest
+ public void testPhoneNumbersEqual() throws Exception {
+ mDatabase.execSQL("CREATE TABLE phones (num TEXT);");
+ mDatabase.execSQL("INSERT INTO phones (num) VALUES ('911');");
+ mDatabase.execSQL("INSERT INTO phones (num) VALUES ('5555');");
+ mDatabase.execSQL("INSERT INTO phones (num) VALUES ('+" + PHONE_NUMBER + "');");
+
+ String number;
+ Cursor c;
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '504-555-7683')", null, null, null, null);
+ assertTrue(c == null || c.getCount() == 0);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '911')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("911", number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '5555')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("5555", number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '180055555555')", null, null, null, null);
+ assertTrue(c == null || c.getCount() == 0);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '+" + PHONE_NUMBER + "')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '+1 (617).555-1212')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '+1 (617).555-1212p1234')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '" + PHONE_NUMBER + "')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '5551212')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '011" + PHONE_NUMBER + "')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+
+ c = mDatabase.query("phones", null,
+ "PHONE_NUMBERS_EQUAL(num, '00" + PHONE_NUMBER + "')", null, null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ number = c.getString(c.getColumnIndexOrThrow("num"));
+ assertEquals("+" + PHONE_NUMBER, number);
+ c.close();
+ }
+
+ /**
+ * Tests international matching issues for the PHONE_NUMBERS_EQUAL function.
+ *
+ * @throws Exception
+ */
+ public void testPhoneNumbersEqualInternationl() throws Exception {
+ Cursor c;
+ String[] phoneNumbers = new String[2];
+
+ // Russian trunk digit
+ phoneNumbers[0] = "+79161234567"; // globablly dialable number
+ phoneNumbers[1] = "89161234567"; // in-country dialable number
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("equal", c.getString(0));
+ c.close();
+
+ // French trunk digit
+ phoneNumbers[0] = "+33123456789"; // globablly dialable number
+ phoneNumbers[1] = "0123456789"; // in-country dialable number
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("equal", c.getString(0));
+ c.close();
+
+
+ // Trunk digit for city codes in the Netherlands
+ phoneNumbers[0] = "+31771234567"; // globablly dialable number
+ phoneNumbers[1] = "0771234567"; // in-country dialable number
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("equal", c.getString(0));
+ c.close();
+
+ // Test broken caller ID seen on call from Thailand to the US
+ phoneNumbers[0] = "+66811234567"; // in address book
+ phoneNumbers[1] = "166811234567"; // came in from the network
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("equal", c.getString(0));
+ c.close();
+
+ // Test the same in-country number with different country codes
+ phoneNumbers[0] = "+33123456789";
+ phoneNumbers[1] = "+1123456789";
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("not equal", c.getString(0));
+ c.close();
+
+ // Test one number with country code and the other without
+ phoneNumbers[0] = "5125551212";
+ phoneNumbers[1] = "+15125551212";
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("equal", c.getString(0));
+ c.close();
+
+ // Test two NANP numbers that only differ in the area code
+ phoneNumbers[0] = "5125551212";
+ phoneNumbers[1] = "6505551212";
+ c = mDatabase.rawQuery(
+ "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END",
+ phoneNumbers);
+ assertTrue(c.moveToFirst());
+ assertEquals("not equal", c.getString(0));
+ c.close();
+ }
+
+ @MediumTest
+ public void testCopyString() throws Exception {
+ mDatabase.execSQL("CREATE TABLE guess (numi INTEGER, numf FLOAT, str TEXT);");
+ mDatabase.execSQL(
+ "INSERT INTO guess (numi,numf,str) VALUES (0,0.0,'ZoomZoomZoomZoom');");
+ mDatabase.execSQL("INSERT INTO guess (numi,numf,str) VALUES (2000000000,3.1415926535,'');");
+ String chinese = "\u4eac\u4ec5 \u5c3d\u5f84\u60ca";
+ String[] arr = new String[1];
+ arr[0] = chinese;
+ mDatabase.execSQL("INSERT INTO guess (numi,numf,str) VALUES (-32768,-1.0,?)", arr);
+
+ Cursor c;
+
+ c = mDatabase.rawQuery("SELECT * FROM guess", null);
+
+ c.moveToFirst();
+
+ CharArrayBuffer buf = new CharArrayBuffer(14);
+
+ String compareTo = c.getString(c.getColumnIndexOrThrow("numi"));
+ int numiIdx = c.getColumnIndexOrThrow("numi");
+ int numfIdx = c.getColumnIndexOrThrow("numf");
+ int strIdx = c.getColumnIndexOrThrow("str");
+
+ c.copyStringToBuffer(numiIdx, buf);
+ assertEquals(1, buf.sizeCopied);
+ assertEquals(compareTo, new String(buf.data, 0, buf.sizeCopied));
+
+ c.copyStringToBuffer(strIdx, buf);
+ assertEquals("ZoomZoomZoomZoom", new String(buf.data, 0, buf.sizeCopied));
+
+ c.moveToNext();
+ compareTo = c.getString(numfIdx);
+
+ c.copyStringToBuffer(numfIdx, buf);
+ assertEquals(compareTo, new String(buf.data, 0, buf.sizeCopied));
+ c.copyStringToBuffer(strIdx, buf);
+ assertEquals(0, buf.sizeCopied);
+
+ c.moveToNext();
+ c.copyStringToBuffer(numfIdx, buf);
+ assertEquals(-1.0, Double.valueOf(
+ new String(buf.data, 0, buf.sizeCopied)).doubleValue());
+
+ c.copyStringToBuffer(strIdx, buf);
+ compareTo = c.getString(strIdx);
+ assertEquals(chinese, compareTo);
+
+ assertEquals(chinese, new String(buf.data, 0, buf.sizeCopied));
+ c.close();
+ }
+
+ @MediumTest
+ public void testSchemaChange1() throws Exception {
+ SQLiteDatabase db1 = mDatabase;
+ Cursor cursor;
+
+ db1.execSQL("CREATE TABLE db1 (_id INTEGER PRIMARY KEY, data TEXT);");
+
+ cursor = db1.query("db1", null, null, null, null, null, null);
+ assertNotNull("Cursor is null", cursor);
+
+ db1.execSQL("CREATE TABLE db2 (_id INTEGER PRIMARY KEY, data TEXT);");
+
+ assertEquals(0, cursor.getCount());
+ cursor.deactivate();
+ }
+
+ @MediumTest
+ public void testSchemaChange2() throws Exception {
+ SQLiteDatabase db1 = mDatabase;
+ SQLiteDatabase db2 = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile, null);
+ Cursor cursor;
+
+ db1.execSQL("CREATE TABLE db1 (_id INTEGER PRIMARY KEY, data TEXT);");
+
+ cursor = db1.query("db1", null, null, null, null, null, null);
+ assertNotNull("Cursor is null", cursor);
+ assertEquals(0, cursor.getCount());
+ cursor.deactivate();
+ // this cause exception because we're still using sqlite_prepate16 and not
+ // sqlite_prepare16_v2. The v2 variant added the ability to check the
+ // schema version and handle the case when the schema has changed
+ // Marco Nelissen claim it was 2x slower to compile SQL statements so
+ // I reverted back to the v1 variant.
+ /* db2.execSQL("CREATE TABLE db2 (_id INTEGER PRIMARY KEY, data TEXT);");
+
+ cursor = db1.query("db1", null, null, null, null, null, null);
+ assertNotNull("Cursor is null", cursor);
+ assertEquals(0, cursor.count());
+ cursor.deactivate();
+ */
+ }
+
+ @MediumTest
+ public void testSchemaChange3() throws Exception {
+ SQLiteDatabase db1 = mDatabase;
+ SQLiteDatabase db2 = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile, null);
+ Cursor cursor;
+
+
+ db1.execSQL("CREATE TABLE db1 (_id INTEGER PRIMARY KEY, data TEXT);");
+ db1.execSQL("INSERT INTO db1 (data) VALUES ('test');");
+
+ cursor = db1.query("db1", null, null, null, null, null, null);
+ // this cause exception because we're still using sqlite_prepate16 and not
+ // sqlite_prepare16_v2. The v2 variant added the ability to check the
+ // schema version and handle the case when the schema has changed
+ // Marco Nelissen claim it was 2x slower to compile SQL statements so
+ // I reverted back to the v1 variant.
+ /* db2.execSQL("CREATE TABLE db2 (_id INTEGER PRIMARY KEY, data TEXT);");
+
+ assertNotNull("Cursor is null", cursor);
+ assertEquals(1, cursor.count());
+ assertTrue(cursor.first());
+ assertEquals("test", cursor.getString(cursor.getColumnIndexOrThrow("data")));
+ cursor.deactivate();
+ */
+ }
+
+ private class ChangeObserver extends ContentObserver {
+ private int mCursorNotificationCount = 0;
+ private int mNotificationCount = 0;
+
+ public int getCursorNotificationCount() {
+ return mCursorNotificationCount;
+ }
+
+ public int getNotificationCount() {
+ return mNotificationCount;
+ }
+
+ public ChangeObserver(boolean cursor) {
+ super(new Handler());
+ mCursor = cursor;
+ }
+
+ @Override
+ public boolean deliverSelfNotifications() {
+ return true;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ if (mCursor) {
+ mCursorNotificationCount++;
+ } else {
+ mNotificationCount++;
+ }
+ }
+
+ boolean mCursor;
+ }
+
+ @MediumTest
+ public void testNotificationTest1() throws Exception {
+ /*
+ Cursor c = mContentResolver.query(Notes.CONTENT_URI,
+ new String[] {Notes._ID, Notes.NOTE},
+ null, null);
+ c.registerContentObserver(new MyContentObserver(true));
+ int count = c.count();
+
+ MyContentObserver observer = new MyContentObserver(false);
+ mContentResolver.registerContentObserver(Notes.CONTENT_URI, true, observer);
+
+ Uri uri;
+
+ HashMap<String, String> values = new HashMap<String, String>();
+ values.put(Notes.NOTE, "test note1");
+ uri = mContentResolver.insert(Notes.CONTENT_URI, values);
+ assertEquals(1, mCursorNotificationCount);
+ assertEquals(1, mNotificationCount);
+
+ c.requery();
+ assertEquals(count + 1, c.count());
+ c.first();
+ assertEquals("test note1", c.getString(c.getColumnIndex(Notes.NOTE)));
+ c.updateString(c.getColumnIndex(Notes.NOTE), "test note2");
+ c.commitUpdates();
+
+ assertEquals(2, mCursorNotificationCount);
+ assertEquals(2, mNotificationCount);
+
+ mContentResolver.delete(uri, null);
+
+ assertEquals(3, mCursorNotificationCount);
+ assertEquals(3, mNotificationCount);
+
+ mContentResolver.unregisterContentObserver(observer);
+ */
+ }
+
+ @MediumTest
+ public void testSelectionArgs() throws Exception {
+ mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
+ ContentValues values = new ContentValues(1);
+ values.put("data", "don't forget to handled 's");
+ mDatabase.insert("test", "data", values);
+ values.clear();
+ values.put("data", "no apostrophes here");
+ mDatabase.insert("test", "data", values);
+ Cursor c = mDatabase.query(
+ "test", null, "data GLOB ?", new String[]{"*'*"}, null, null, null);
+ assertEquals(1, c.getCount());
+ assertTrue(c.moveToFirst());
+ assertEquals("don't forget to handled 's", c.getString(1));
+ c.deactivate();
+
+ // make sure code should checking null string properly so that
+ // it won't crash
+ try {
+ mDatabase.query("test", new String[]{"_id"},
+ "_id=?", new String[]{null}, null, null, null);
+ fail("expected exception not thrown");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ @MediumTest
+ public void testTokenize() throws Exception {
+ Cursor c;
+ mDatabase.execSQL("CREATE TABLE tokens (" +
+ "token TEXT COLLATE unicode," +
+ "source INTEGER " +
+ ");");
+ String[] cols = new String[]{"token", "source"};
+
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE(NULL, NULL, NULL, NULL)", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens', NULL, NULL, NULL)", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens', 10, NULL, NULL)", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens', 10, 'some string', NULL)", null));
+
+ Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens', 1, 'some string ok', ' ')", null));
+
+ // test Chinese
+ String chinese = new String("\u4eac\u4ec5 \u5c3d\u5f84\u60ca");
+ Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens', 1,'" + chinese + "', ' ')", null));
+
+ String icustr = new String("Fr\u00e9d\u00e9ric Hj\u00f8nnev\u00e5g");
+
+ Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens', 1, '" + icustr + "', ' ')", null));
+
+ Assert.assertEquals(7, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens;", null));
+
+ String key = DatabaseUtils.getHexCollationKey("Frederic Hjonneva");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ key = DatabaseUtils.getHexCollationKey("Hjonneva");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+
+ key = DatabaseUtils.getHexCollationKey("some string ok");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ key = DatabaseUtils.getHexCollationKey("string");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ key = DatabaseUtils.getHexCollationKey("ok");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+
+ key = DatabaseUtils.getHexCollationKey(chinese);
+ String[] a = new String[1];
+ a[0] = key;
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token= ?", a));
+ a[0] += "*";
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB ?", a));
+
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token= '" + key + "'", null));
+
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+
+ key = DatabaseUtils.getHexCollationKey("\u4eac\u4ec5");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+
+
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB 'ab*'", null));
+ }
+
+ @MediumTest
+ public void testTransactions() throws Exception {
+ mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
+ mDatabase.execSQL("INSERT INTO test (num) VALUES (0)");
+
+ // Make sure that things work outside an explicit transaction.
+ setNum(1);
+ checkNum(1);
+
+ // Test a single-level transaction.
+ setNum(0);
+ mDatabase.beginTransaction();
+ setNum(1);
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ checkNum(1);
+ Assert.assertFalse(mDatabase.isDbLockedByCurrentThread());
+
+ // Test a rolled-back transaction.
+ setNum(0);
+ mDatabase.beginTransaction();
+ setNum(1);
+ mDatabase.endTransaction();
+ checkNum(0);
+ Assert.assertFalse(mDatabase.isDbLockedByCurrentThread());
+
+ // We should get an error if we end a non-existent transaction.
+ assertThrowsIllegalState(new Runnable() { public void run() {
+ mDatabase.endTransaction();
+ }});
+
+ // We should get an error if a set a non-existent transaction as clean.
+ assertThrowsIllegalState(new Runnable() { public void run() {
+ mDatabase.setTransactionSuccessful();
+ }});
+
+ mDatabase.beginTransaction();
+ mDatabase.setTransactionSuccessful();
+ // We should get an error if we mark a transaction as clean twice.
+ assertThrowsIllegalState(new Runnable() { public void run() {
+ mDatabase.setTransactionSuccessful();
+ }});
+ // We should get an error if we begin a transaction after marking the parent as clean.
+ assertThrowsIllegalState(new Runnable() { public void run() {
+ mDatabase.beginTransaction();
+ }});
+ mDatabase.endTransaction();
+ Assert.assertFalse(mDatabase.isDbLockedByCurrentThread());
+
+ // Test a two-level transaction.
+ setNum(0);
+ mDatabase.beginTransaction();
+ mDatabase.beginTransaction();
+ setNum(1);
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ checkNum(1);
+ Assert.assertFalse(mDatabase.isDbLockedByCurrentThread());
+
+ // Test rolling back an inner transaction.
+ setNum(0);
+ mDatabase.beginTransaction();
+ mDatabase.beginTransaction();
+ setNum(1);
+ mDatabase.endTransaction();
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ checkNum(0);
+ Assert.assertFalse(mDatabase.isDbLockedByCurrentThread());
+
+ // Test rolling back an outer transaction.
+ setNum(0);
+ mDatabase.beginTransaction();
+ mDatabase.beginTransaction();
+ setNum(1);
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+ mDatabase.endTransaction();
+ checkNum(0);
+ Assert.assertFalse(mDatabase.isDbLockedByCurrentThread());
+ }
+
+ private void setNum(int num) {
+ mDatabase.execSQL("UPDATE test SET num = " + num);
+ }
+
+ private void checkNum(int num) {
+ Assert.assertEquals(
+ num, DatabaseUtils.longForQuery(mDatabase, "SELECT num FROM test", null));
+ }
+
+ private void assertThrowsIllegalState(Runnable r) {
+ boolean ok = false;
+ try {
+ r.run();
+ } catch (IllegalStateException e) {
+ ok = true;
+ }
+ Assert.assertTrue(ok);
+ }
+
+ // Disable these until we can explicitly mark them as stress tests
+ public void xxtestMem1() throws Exception {
+ populateDefaultTable();
+
+ for (int i = 0; i < 50000; i++) {
+ Cursor cursor = mDatabase.query("test", null, null, null, null, null, null);
+ cursor.moveToFirst();
+ cursor.close();
+// Log.i("~~~~", "Finished round " + i);
+ }
+ }
+
+ // Disable these until we can explicitly mark them as stress tests
+ public void xxtestMem2() throws Exception {
+ populateDefaultTable();
+
+ for (int i = 0; i < 50000; i++) {
+ Cursor cursor = mDatabase.query("test", null, null, null, null, null, null);
+ cursor.close();
+// Log.i("~~~~", "Finished round " + i);
+ }
+ }
+
+ // Disable these until we can explicitly mark them as stress tests
+ public void xxtestMem3() throws Exception {
+ populateDefaultTable();
+
+ for (int i = 0; i < 50000; i++) {
+ Cursor cursor = mDatabase.query("test", null, null, null, null, null, null);
+ cursor.deactivate();
+// Log.i("~~~~", "Finished round " + i);
+ }
+ }
+
+ @MediumTest
+ public void testContentValues() throws Exception {
+ ContentValues values = new ContentValues();
+ values.put("string", "value");
+ assertEquals("value", values.getAsString("string"));
+ byte[] bytes = new byte[42];
+ Arrays.fill(bytes, (byte) 0x28);
+ values.put("byteArray", bytes);
+ assertTrue(Arrays.equals(bytes, values.getAsByteArray("byteArray")));
+
+ // Write the ContentValues to a Parcel and then read them out
+ Parcel p = Parcel.obtain();
+ values.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ values = ContentValues.CREATOR.createFromParcel(p);
+
+ // Read the values out again and make sure they're the same
+ assertTrue(Arrays.equals(bytes, values.getAsByteArray("byteArray")));
+ assertEquals("value", values.get("string"));
+ }
+
+ @MediumTest
+ public void testTableInfoPragma() throws Exception {
+ mDatabase.execSQL("CREATE TABLE pragma_test (" +
+ "i INTEGER DEFAULT 1234, " +
+ "j INTEGER, " +
+ "s TEXT DEFAULT 'hello', " +
+ "t TEXT, " +
+ "'select' TEXT DEFAULT \"hello\")");
+ try {
+ Cursor cur = mDatabase.rawQuery("PRAGMA table_info(pragma_test)", null);
+ Assert.assertEquals(5, cur.getCount());
+
+ Assert.assertTrue(cur.moveToNext());
+ Assert.assertEquals("i",
+ cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX));
+ Assert.assertEquals("1234",
+ cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX));
+
+ Assert.assertTrue(cur.moveToNext());
+ Assert.assertEquals("j",
+ cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX));
+ Assert.assertNull(cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX));
+
+ Assert.assertTrue(cur.moveToNext());
+ Assert.assertEquals("s",
+ cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX));
+ Assert.assertEquals("'hello'",
+ cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX));
+
+ Assert.assertTrue(cur.moveToNext());
+ Assert.assertEquals("t",
+ cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX));
+ Assert.assertNull(cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX));
+
+ Assert.assertTrue(cur.moveToNext());
+ Assert.assertEquals("select",
+ cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX));
+ Assert.assertEquals("\"hello\"",
+ cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX));
+
+ cur.close();
+ } catch (Throwable t) {
+ throw new RuntimeException(
+ "If you see this test fail, it's likely that something about " +
+ "sqlite's PRAGMA table_info(...) command has changed.", t);
+ }
+ }
+
+ @MediumTest
+ public void testInsertHelper() throws Exception {
+ Cursor cur;
+ ContentValues cv;
+ long row;
+
+ mDatabase.execSQL("CREATE TABLE insert_test (" +
+ "_id INTEGER PRIMARY KEY, " +
+ "s TEXT NOT NULL UNIQUE, " +
+ "t TEXT NOT NULL DEFAULT 'hello world', " +
+ "i INTEGER, " +
+ "j INTEGER NOT NULL DEFAULT 1234, " +
+ "'select' TEXT)");
+
+ DatabaseUtils.InsertHelper ih =
+ new DatabaseUtils.InsertHelper(mDatabase, "insert_test");
+
+ cv = new ContentValues();
+ cv.put("s", "one");
+ row = ih.insert(cv);
+ cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null);
+ Assert.assertTrue(cur.moveToFirst());
+ Assert.assertEquals("one", cur.getString(1));
+ Assert.assertEquals("hello world", cur.getString(2));
+ Assert.assertNull(cur.getString(3));
+ Assert.assertEquals(1234, cur.getLong(4));
+ Assert.assertNull(cur.getString(5));
+
+ cv = new ContentValues();
+ cv.put("s", "two");
+ cv.put("t", "goodbye world");
+ row = ih.insert(cv);
+ cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null);
+ Assert.assertTrue(cur.moveToFirst());
+ Assert.assertEquals("two", cur.getString(1));
+ Assert.assertEquals("goodbye world", cur.getString(2));
+ Assert.assertNull(cur.getString(3));
+ Assert.assertEquals(1234, cur.getLong(4));
+ Assert.assertNull(cur.getString(5));
+
+ cv = new ContentValues();
+ cv.put("t", "goodbye world");
+ row = ih.insert(cv);
+ Assert.assertEquals(-1, row);
+
+ cv = new ContentValues();
+ cv.put("s", "three");
+ cv.put("i", 2345);
+ cv.put("j", 3456);
+ cv.put("select", "tricky");
+ row = ih.insert(cv);
+ cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null);
+ Assert.assertTrue(cur.moveToFirst());
+ Assert.assertEquals("three", cur.getString(1));
+ Assert.assertEquals("hello world", cur.getString(2));
+ Assert.assertEquals(2345, cur.getLong(3));
+ Assert.assertEquals(3456, cur.getLong(4));
+ Assert.assertEquals("tricky", cur.getString(5));
+
+ cv = new ContentValues();
+ cv.put("s", "three");
+ cv.put("i", 6789);
+ row = ih.insert(cv);
+ Assert.assertEquals(-1, row);
+ row = ih.replace(cv);
+ cur = mDatabase.rawQuery("SELECT * FROM insert_test WHERE _id == " + row, null);
+ Assert.assertTrue(cur.moveToFirst());
+ Assert.assertEquals("three", cur.getString(1));
+ Assert.assertEquals("hello world", cur.getString(2));
+ Assert.assertEquals(6789, cur.getLong(3));
+
+ ih.close();
+ }
+
+}