Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch openseedatabase Excluding Merge-Ins
This is equivalent to a diff from be6acc5363 to 6f17178a68
2013-12-24
| ||
12:07 | In SQLITE_HAS_CODEC builds, do not initialize the LOCALIZED collation automatically (as if the SQLiteDatabase.NO_LOCALIZED_COLLATORS flag was set). Require apps to call the enableLocalizedCollators() method to explicitly initialize it. This gives the app an opportunity to execute a PRAGMA statement to configure an encryption key before the database is first accessed. (check-in: 9c4a073c3b user: dan tags: trunk) | |
10:14 | Add extra SEE tests. (Leaf check-in: 6f17178a68 user: dan tags: openseedatabase) | |
2013-12-23
| ||
18:23 | Add support for SEE, SQLite's encryption extension. (check-in: 409082dd02 user: dan tags: openseedatabase) | |
07:33 | Add extra required utility functions to ExtraUtils.java. (check-in: be6acc5363 user: dan tags: trunk) | |
2013-12-21
| ||
19:32 | Update jni/README. (check-in: 1b80ccf163 user: dan tags: trunk) | |
Changes to jni/Android.mk.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | + - - + + + + + + + + + + | LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS += -DHAVE_CONFIG_H -DKHTML_NO_EXCEPTIONS -DGKWQ_NO_JAVA LOCAL_CFLAGS += -DNO_SUPPORT_JS_BINDING -DQT_NO_WHEELEVENT -DKHTML_NO_XBL LOCAL_CFLAGS += -U__APPLE__ LOCAL_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses LOCAL_CPPFLAGS += -Wno-conversion-null ifeq ($(TARGET_ARCH), arm) LOCAL_CFLAGS += -DPACKED="__attribute__ ((packed))" else LOCAL_CFLAGS += -DPACKED="" endif LOCAL_SRC_FILES:= \ android_database_SQLiteCommon.cpp \ android_database_SQLiteConnection.cpp \ android_database_SQLiteGlobal.cpp \ android_database_SQLiteDebug.cpp \ |
︙ |
Changes to jni/android_database_SQLiteConnection.cpp.
︙ | |||
849 850 851 852 853 854 855 856 857 858 859 860 861 862 | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 | + + + + + + + + + + + + + + + + + + + + + + + + | sqlite3_progress_handler(connection->db, 4, sqliteProgressHandlerCallback, connection); } else { sqlite3_progress_handler(connection->db, 0, NULL, NULL); } } static void nativeSetSeeKey(JNIEnv *pEnv, jobject clazz, jint connectionPtr, jstring zKey){ SQLiteConnection* p = reinterpret_cast<SQLiteConnection*>(connectionPtr); sqlite3_stmt *pStmt = 0; int rc; const char *zUtf8 = pEnv->GetStringUTFChars(zKey, 0); char *zSql = sqlite3_mprintf("PRAGMA key = '%q'", zUtf8); ALOG(LOG_ERROR, SQLITE_TRACE_TAG, "nativeSetSeeKey: %s", zSql); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); if( rc==SQLITE_OK ){ sqlite3_step(pStmt); rc = sqlite3_finalize(pStmt); } pEnv->ReleaseStringUTFChars(zKey, zUtf8); sqlite3_free(zSql); if( rc!=SQLITE_OK ){ char *zErr = sqlite3_mprintf("nativeSetSeeKey %d \"%s\"", rc, sqlite3_errmsg(p->db)); throw_sqlite3_exception(pEnv, p->db, zErr); } } static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)I", (void*)nativeOpen }, { "nativeClose", "(I)V", |
︙ | |||
905 906 907 908 909 910 911 912 913 914 915 916 917 918 | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | + + | (void*)nativeExecuteForCursorWindow }, { "nativeGetDbLookaside", "(I)I", (void*)nativeGetDbLookaside }, { "nativeCancel", "(I)V", (void*)nativeCancel }, { "nativeResetCancel", "(IZ)V", (void*)nativeResetCancel }, { "nativeSetSeeKey", "(ILjava/lang/String;)V", (void*)nativeSetSeeKey }, }; #define FIND_CLASS(var, className) \ var = env->FindClass(className); \ LOG_FATAL_IF(! var, "Unable to find class " className); #define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ |
︙ |
Changes to src/org/sqlite/app/customsqlite/CustomSqlite.java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | + + + + + + + + + + + + + + + + + | package org.sqlite.app.customsqlite; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import java.io.File; import java.io.FileInputStream; import java.util.Arrays; import java.lang.InterruptedException; import org.sqlite.database.sqlite.SQLiteDatabase; import org.sqlite.database.sqlite.SQLiteStatement; import org.sqlite.database.sqlite.SQLiteDatabaseCorruptException; import android.database.Cursor; /* import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; */ import org.sqlite.database.DatabaseErrorHandler; class DoNotDeleteErrorHandler implements DatabaseErrorHandler { private static final String TAG = "DoNotDeleteErrorHandler"; public void onCorruption(SQLiteDatabase dbObj) { Log.e(TAG, "Corruption reported by sqlite on database: " + dbObj.getPath()); } } public class CustomSqlite extends Activity { private TextView myTV; /* Text view widget */ private int myNTest; /* Number of tests attempted */ private int myNErr; /* Number of tests failed */ File DB_PATH; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); myTV = (TextView)findViewById(R.id.tv_widget); |
︙ | |||
56 57 58 59 60 61 62 63 64 65 66 | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + | } else { myNErr++; myTV.append("FAILED\n"); myTV.append(" res= \"" + res + "\"\n"); myTV.append(" expected=\"" + expected + "\"\n"); } } /* ** Test if the database at DB_PATH is encrypted or not. The db ** is assumed to be encrypted if the first 6 bytes are anything ** other than "SQLite". ** ** If the test reveals that the db is encrypted, return the string ** "encrypted". Otherwise, "unencrypted". */ public String db_is_encrypted() throws Exception { FileInputStream in = new FileInputStream(DB_PATH); byte[] buffer = new byte[6]; in.read(buffer, 0, 6); String res = "encrypted"; if( Arrays.equals(buffer, (new String("SQLite")).getBytes()) ){ res = "unencrypted"; } return res; } /* ** Test that a database connection may be accessed from a second thread. */ public void thread_test_1(){ SQLiteDatabase.deleteDatabase(DB_PATH); final SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null); String db_path2 = DB_PATH.toString() + "2"; db.execSQL("CREATE TABLE t1(x, y)"); db.execSQL("INSERT INTO t1 VALUES (1, 2), (3, 4)"); Thread t = new Thread( new Runnable() { public void run() { SQLiteStatement st = db.compileStatement("SELECT sum(x+y) FROM t1"); String res = st.simpleQueryForString(); test_result("thread_test_1", res, "10"); } }); t.start(); try { t.join(); } catch (InterruptedException e) { } } /* ** Use a Cursor to loop through the results of a SELECT query. */ |
Changes to src/org/sqlite/database/sqlite/SQLiteConnection.java.
︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | + | int connectionPtr, int statementPtr); private static native long nativeExecuteForCursorWindow( int connectionPtr, int statementPtr, CursorWindow win, int startPos, int requiredPos, boolean countAllRows); private static native int nativeGetDbLookaside(int connectionPtr); private static native void nativeCancel(int connectionPtr); private static native void nativeResetCancel(int connectionPtr, boolean cancelable); private static native void nativeSetSeeKey(int connectionPtr, String key); private SQLiteConnection(SQLiteConnectionPool pool, SQLiteDatabaseConfiguration configuration, int connectionId, boolean primaryConnection) { mPool = pool; mConfiguration = new SQLiteDatabaseConfiguration(configuration); mConnectionId = connectionId; |
︙ | |||
206 207 208 209 210 211 212 213 214 215 216 217 218 219 | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | + + + + + | dispose(false); } private void open() { mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags, mConfiguration.label, SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME); if( mConfiguration.bSee ){ nativeSetSeeKey(mConnectionPtr, mConfiguration.seekey); mConfiguration.setSeeKey(null); } setPageSize(); setForeignKeyModeFromConfiguration(); setWalModeFromConfiguration(); setJournalSizeLimit(); setAutoCheckpointInterval(); setLocaleFromConfiguration(); |
︙ | |||
416 417 418 419 420 421 422 | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | - + | & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0; boolean localeChanged = !configuration.locale.equals(mConfiguration.locale); // Update configuration parameters. mConfiguration.updateParametersFrom(configuration); // Update prepared statement cache size. |
︙ |
Changes to src/org/sqlite/database/sqlite/SQLiteConnectionPool.java.
︙ | |||
180 181 182 183 184 185 186 187 188 189 190 191 192 193 | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | + + | // Might throw private void open() { // Open the primary connection. // This might throw if the database is corrupt. mAvailablePrimaryConnection = openConnectionLocked(mConfiguration, true /*primaryConnection*/); // might throw mConfiguration.setSeeKey(null); // Mark the pool as being open for business. mIsOpen = true; mCloseGuard.open("close"); } /** |
︙ |
Changes to src/org/sqlite/database/sqlite/SQLiteDatabase.java.
︙ | |||
691 692 693 694 695 696 697 698 699 700 701 702 703 704 | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | + + + + + + + + + + + + + + | */ public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, DatabaseErrorHandler errorHandler) { SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler); db.open(); return db; } public static SQLiteDatabase openSeeDatabase( String path, String key, CursorFactory factory, int flags, DatabaseErrorHandler errorHandler ){ SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler); db.mConfigurationLocked.setSeeKey(key); db.open(); db.mConfigurationLocked.setSeeKey(null); return db; } /** * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY). */ public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) { return openOrCreateDatabase(file.getPath(), factory); } |
︙ | |||
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 | + + + + | /** * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler). */ public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory, DatabaseErrorHandler errorHandler) { return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler); } /** * Deletes a database including its journal file and other auxiliary files * that may have been created by the database engine. * * @param file The database file path. * @return True if the database was successfully deleted. */ public static boolean deleteDatabase(File file) { if (file == null) { throw new IllegalArgumentException("file must not be null"); } boolean deleted = false; deleted |= file.delete(); deleted |= new File(file.getPath() + "-journal").delete(); deleted |= new File(file.getPath() + "-shm").delete(); deleted |= new File(file.getPath() + "-wal").delete(); /* TODO: This is throwing a NullPointerException. Do not know why. */ /* File dir = file.getParentFile(); if (dir != null) { final String prefix = file.getName() + "-mj"; final FileFilter filter = new FileFilter() { @Override public boolean accept(File candidate) { return candidate.getName().startsWith(prefix); } }; for (File masterJournal : dir.listFiles(filter)) { deleted |= masterJournal.delete(); } } */ return deleted; } /** * Reopens the database in read-write mode. * If the database is already read-write, does nothing. * |
︙ |
Changes to src/org/sqlite/database/sqlite/SQLiteDatabaseConfiguration.java.
︙ | |||
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | + + + + + + + + + + + + + + + + + + + + + + | /** * The custom functions to register. */ public final ArrayList<SQLiteCustomFunction> customFunctions = new ArrayList<SQLiteCustomFunction>(); /* ** The following two variables are used by the SEE extension. */ public boolean bSee; public String seekey; /* ** Function to set SEE related variables. */ public void setSeeKey(String key){ bSee = true; seekey = key; } /** * Creates a database configuration with the required parameters for opening a * database and default values for all other parameters. * * @param path The database path. * @param openFlags Open flags for the database, such as {@link SQLiteDatabase#OPEN_READWRITE}. */ public SQLiteDatabaseConfiguration(String path, int openFlags) { if (path == null) { throw new IllegalArgumentException("path must not be null."); } this.path = path; label = stripPathForLogs(path); this.openFlags = openFlags; // Set default values for optional parameters. maxSqlCacheSize = 25; locale = Locale.getDefault(); // Set default values for SEE parameters (default is unencrypted). bSee = false; seekey = null; } /** * Creates a database configuration as a copy of another configuration. * * @param other The other configuration. */ public SQLiteDatabaseConfiguration(SQLiteDatabaseConfiguration other) { if (other == null) { throw new IllegalArgumentException("other must not be null."); } this.path = other.path; this.label = other.label; updateParametersFrom(other); this.bSee = other.bSee; this.seekey = other.seekey; } /** * Updates the non-immutable parameters of this configuration object * from the other configuration object. * * @param other The object from which to copy the parameters. |
︙ |