SQLite Android Bindings
Check-in [7e57f15de2]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Commit the various hacks to android files made outside of fossil.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7e57f15de2d70c9f053347e55b89e7437f3becfe
User & Date: dan 2013-12-18 17:23:55
Context
2013-12-18
17:36
Update CustomSqlite.java to call "SELECT sqlite_version()". check-in: 71a3449ef6 user: dan tags: trunk
17:23
Commit the various hacks to android files made outside of fossil. check-in: 7e57f15de2 user: dan tags: trunk
17:02
Copy in some Android files. check-in: 77eacc52c5 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added jni/Android.mk.

































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

ANDROIDSRC = /home/dan/big/Android

JNI_H_INCLUDE = $(ANDROIDSRC)/libnativehelper/include/nativehelper/

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  \
	sqlite3.c

LOCAL_SRC_FILES += \
	JNIHelp.cpp \
	JniConstants.cpp 


LOCAL_C_INCLUDES += \
	$(JNI_H_INCLUDE) \
	$(ANDROIDSRC)/system/core/include/ \
	$(ANDROIDSRC)/frameworks/base/include/ \
	$(ANDROIDSRC)/frameworks/native/include/ \
	$(ANDROIDSRC)/libnativehelper/include/ \
	$(ANDROIDSRC)/frameworks/base/core/jni \


LOCAL_MODULE:= libsqliteX

LOCAL_LDLIBS += -ldl -llog 
# LOCAL_LDLIBS += -lnativehelper -landroid_runtime -lutils -lbinder

include $(BUILD_SHARED_LIBRARY)

Added jni/Application.mk.



>
1
APP_STL:=stlport_static

Changes to jni/JNIHelp.cpp.

69
70
71
72
73
74
75

76
77
78
79
80
81
82

extern "C" int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
    const JNINativeMethod* gMethods, int numMethods)
{
    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);

    ALOGV("Registering %s's %d native methods...", className, numMethods);


    scoped_local_ref<jclass> c(env, findClass(env, className));
    if (c.get() == NULL) {
        char* msg;
        asprintf(&msg, "Native registration unable to find class '%s'; aborting...", className);
        e->FatalError(msg);
    }







>







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

extern "C" int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
    const JNINativeMethod* gMethods, int numMethods)
{
    JNIEnv* e = reinterpret_cast<JNIEnv*>(env);

    ALOGV("Registering %s's %d native methods...", className, numMethods);
    __android_log_print(ANDROID_LOG_INFO,  __FUNCTION__, "Registering");

    scoped_local_ref<jclass> c(env, findClass(env, className));
    if (c.get() == NULL) {
        char* msg;
        asprintf(&msg, "Native registration unable to find class '%s'; aborting...", className);
        e->FatalError(msg);
    }

Changes to jni/android_database_SQLiteCommon.cpp.

116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
            exceptionClass = "android/os/OperationCanceledException";
            break;
        default:
            exceptionClass = "android/database/sqlite/SQLiteException";
            break;
    }

    if (sqlite3Message) {

        String8 fullMessage;
        fullMessage.append(sqlite3Message);
        fullMessage.appendFormat(" (code %d)", errcode); // print extended error code
        if (message) {
            fullMessage.append(": ");
            fullMessage.append(message);
        }
        jniThrowException(env, exceptionClass, fullMessage.string());

    } else {
        jniThrowException(env, exceptionClass, message);
    }
}


} // namespace android







|
>








>







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
            exceptionClass = "android/os/OperationCanceledException";
            break;
        default:
            exceptionClass = "android/database/sqlite/SQLiteException";
            break;
    }

    if (0 && sqlite3Message) {
#if 0
        String8 fullMessage;
        fullMessage.append(sqlite3Message);
        fullMessage.appendFormat(" (code %d)", errcode); // print extended error code
        if (message) {
            fullMessage.append(": ");
            fullMessage.append(message);
        }
        jniThrowException(env, exceptionClass, fullMessage.string());
#endif
    } else {
        jniThrowException(env, exceptionClass, message);
    }
}


} // namespace android

Changes to jni/android_database_SQLiteConnection.cpp.

29
30
31
32
33
34
35

36

37
38


39
40
41
42
43
44
45
..
51
52
53
54
55
56
57


58
59
60
61
62
63
64
..
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
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
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
...
189
190
191
192
193
194
195

196

197
198
199
200
201
202
203
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
...
268
269
270
271
272
273
274

275
276
277
278
279
280

281
282
283
284
285
286
287
...
510
511
512
513
514
515
516

517
518
519
520
521
522
523
...
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553
...
567
568
569
570
571
572
573














574
575
576
577
578
579
580
...
669
670
671
672
673
674
675
676
677

678

679
680
681
682
683
684
685
686
687

688

689
690
691
692
693
694
695
...
755
756
757
758
759
760
761

762
763
764
765
766
767
768
...
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
...
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
















#include <string.h>
#include <unistd.h>

#include <androidfw/CursorWindow.h>

#include <sqlite3.h>

#include <sqlite3_android.h>


#include "android_database_SQLiteCommon.h"



// Set to 1 to use UTF16 storage for localized indexes.
#define UTF16_STORAGE 0

namespace android {

/* Busy timeout in milliseconds.
................................................................................
 * have a single open connection at a time unless they are using WAL.  When using
 * WAL, a timeout could occur if one connection is busy performing an auto-checkpoint
 * operation.  The busy timeout needs to be long enough to tolerate slow I/O write
 * operations but not so long as to cause the application to hang indefinitely if
 * there is a problem acquiring a database lock.
 */
static const int BUSY_TIMEOUT_MS = 2500;



static struct {
    jfieldID name;
    jfieldID numArgs;
    jmethodID dispatchCallback;
} gSQLiteCustomFunctionClassInfo;

................................................................................
        OPEN_READ_MASK          = 0x00000001,
        NO_LOCALIZED_COLLATORS  = 0x00000010,
        CREATE_IF_NECESSARY     = 0x10000000,
    };

    sqlite3* const db;
    const int openFlags;
    const String8 path;
    const String8 label;

    volatile bool canceled;

    SQLiteConnection(sqlite3* db, int openFlags, const String8& path, const String8& label) :
        db(db), openFlags(openFlags), path(path), label(label), canceled(false) { }
};

// Called each time a statement begins execution, when tracing is enabled.
static void sqliteTraceCallback(void *data, const char *sql) {
    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
    ALOG(LOG_VERBOSE, SQLITE_TRACE_TAG, "%s: \"%s\"\n",
            connection->label.string(), sql);
}

// Called each time a statement finishes execution, when profiling is enabled.
static void sqliteProfileCallback(void *data, const char *sql, sqlite3_uint64 tm) {
    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
    ALOG(LOG_VERBOSE, SQLITE_PROFILE_TAG, "%s: \"%s\" took %0.3f ms\n",
            connection->label.string(), sql, tm * 0.000001f);
}

// Called after each SQLite VM instruction when cancelation is enabled.
static int sqliteProgressHandlerCallback(void* data) {
    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
    return connection->canceled;
}
................................................................................
    } else if (openFlags & SQLiteConnection::OPEN_READONLY) {
        sqliteFlags = SQLITE_OPEN_READONLY;
    } else {
        sqliteFlags = SQLITE_OPEN_READWRITE;
    }

    const char* pathChars = env->GetStringUTFChars(pathStr, NULL);
    String8 path(pathChars);
    env->ReleaseStringUTFChars(pathStr, pathChars);

    const char* labelChars = env->GetStringUTFChars(labelStr, NULL);
    String8 label(labelChars);
    env->ReleaseStringUTFChars(labelStr, labelChars);

    sqlite3* db;
    int err = sqlite3_open_v2(path.string(), &db, sqliteFlags, NULL);
    if (err != SQLITE_OK) {
        throw_sqlite3_exception_errcode(env, err, "Could not open database");
        return 0;
    }

    // Check that the database is really read/write when that is what we asked for.
    if ((sqliteFlags & SQLITE_OPEN_READWRITE) && sqlite3_db_readonly(db, NULL)) {
................................................................................
    if (err != SQLITE_OK) {
        throw_sqlite3_exception(env, db, "Could not set busy timeout");
        sqlite3_close(db);
        return 0;
    }

    // Register custom Android functions.

    err = register_android_functions(db, UTF16_STORAGE);
    if (err) {
        throw_sqlite3_exception(env, db, "Could not register Android SQL functions.");
        sqlite3_close(db);
        return 0;
    }


    // Create wrapper object.
    SQLiteConnection* connection = new SQLiteConnection(db, openFlags, path, label);

    // Enable tracing and profiling if requested.
    if (enableTrace) {
        sqlite3_trace(db, &sqliteTraceCallback, connection);
    }
    if (enableProfile) {
        sqlite3_profile(db, &sqliteProfileCallback, connection);
    }

    ALOGV("Opened connection %p with label '%s'", db, label.string());
    return reinterpret_cast<jint>(connection);
}

static void nativeClose(JNIEnv* env, jclass clazz, jint connectionPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    if (connection) {
................................................................................
        delete connection;
    }
}

// Called each time a custom function is evaluated.
static void sqliteCustomFunctionCallback(sqlite3_context *context,
        int argc, sqlite3_value **argv) {

    JNIEnv* env = AndroidRuntime::getJNIEnv();


    // Get the callback function object.
    // Create a new local reference to it in case the callback tries to do something
    // dumb like unregister the function (thereby destroying the global ref) while it is running.
    jobject functionObjGlobal = reinterpret_cast<jobject>(sqlite3_user_data(context));
    jobject functionObj = env->NewLocalRef(functionObjGlobal);

................................................................................
        env->ExceptionClear();
    }
}

// Called when a custom function is destroyed.
static void sqliteCustomFunctionDestructor(void* data) {
    jobject functionObjGlobal = reinterpret_cast<jobject>(data);

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    env->DeleteGlobalRef(functionObjGlobal);
}

static void nativeRegisterCustomFunction(JNIEnv* env, jclass clazz, jint connectionPtr,
        jobject functionObj) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

................................................................................
}

static void nativeRegisterLocalizedCollators(JNIEnv* env, jclass clazz, jint connectionPtr,
        jstring localeStr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    const char* locale = env->GetStringUTFChars(localeStr, NULL);

    int err = register_localized_collators(connection->db, locale, UTF16_STORAGE);
    env->ReleaseStringUTFChars(localeStr, locale);

    if (err != SQLITE_OK) {
        throw_sqlite3_exception(env, connection->db);
    }

}

static jint nativePrepareStatement(JNIEnv* env, jclass clazz, jint connectionPtr,
        jstring sqlString) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    jsize sqlLength = env->GetStringLength(sqlString);
................................................................................
            return env->NewString(text, length);
        }
    }
    return NULL;
}

static int createAshmemRegionWithData(JNIEnv* env, const void* data, size_t length) {

    int error = 0;
    int fd = ashmem_create_region(NULL, length);
    if (fd < 0) {
        error = errno;
        ALOGE("ashmem_create_region failed: %s", strerror(error));
    } else {
        if (length > 0) {
................................................................................
                return fd;
            }
        }

        close(fd);
    }


    jniThrowIOException(env, error);
    return -1;
}

static jint nativeExecuteForBlobFileDescriptor(JNIEnv* env, jclass clazz,
        jint connectionPtr, jint statementPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
................................................................................

enum CopyRowResult {
    CPR_OK,
    CPR_FULL,
    CPR_ERROR,
};















static CopyRowResult copyRow(JNIEnv* env, CursorWindow* window,
        sqlite3_stmt* statement, int numColumns, int startPos, int addedRows) {
    // Allocate a new field directory for the row.
    status_t status = window->allocRow();
    if (status) {
        LOG_WINDOW("Failed allocating fieldDir at startPos %d row %d, error=%d",
                startPos, addedRows, status);
................................................................................
        jint startPos, jint requiredPos, jboolean countAllRows) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);

    status_t status = window->clear();
    if (status) {
        String8 msg;
        msg.appendFormat("Failed to clear the cursor window, status=%d", status);

        throw_sqlite3_exception(env, connection->db, msg.string());

        return 0;
    }

    int numColumns = sqlite3_column_count(statement);
    status = window->setNumColumns(numColumns);
    if (status) {
        String8 msg;
        msg.appendFormat("Failed to set the cursor window column count to %d, status=%d",
                numColumns, status);

        throw_sqlite3_exception(env, connection->db, msg.string());

        return 0;
    }

    int retryCount = 0;
    int totalRows = 0;
    int addedRows = 0;
    bool windowFull = false;
................................................................................
    // Report the total number of rows on request.
    if (startPos > totalRows) {
        ALOGE("startPos %d > actual rows %d", startPos, totalRows);
    }
    jlong result = jlong(startPos) << 32 | jlong(totalRows);
    return result;
}


static jint nativeGetDbLookaside(JNIEnv* env, jobject clazz, jint connectionPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    int cur = -1;
    int unused;
    sqlite3_db_status(connection->db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &unused, 0);
................................................................................
static JNINativeMethod sMethods[] =
{
    /* name, signature, funcPtr */
    { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)I",
            (void*)nativeOpen },
    { "nativeClose", "(I)V",
            (void*)nativeClose },
    { "nativeRegisterCustomFunction", "(ILandroid/database/sqlite/SQLiteCustomFunction;)V",
            (void*)nativeRegisterCustomFunction },
    { "nativeRegisterLocalizedCollators", "(ILjava/lang/String;)V",
            (void*)nativeRegisterLocalizedCollators },
    { "nativePrepareStatement", "(ILjava/lang/String;)I",
            (void*)nativePrepareStatement },
    { "nativeFinalizeStatement", "(II)V",
            (void*)nativeFinalizeStatement },
................................................................................

#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find field " fieldName);

int register_android_database_SQLiteConnection(JNIEnv *env)
{

    jclass clazz;
    FIND_CLASS(clazz, "android/database/sqlite/SQLiteCustomFunction");

    GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.name, clazz,
            "name", "Ljava/lang/String;");
    GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.numArgs, clazz,
            "numArgs", "I");
    GET_METHOD_ID(gSQLiteCustomFunctionClassInfo.dispatchCallback,
            clazz, "dispatchCallback", "([Ljava/lang/String;)V");

    FIND_CLASS(clazz, "java/lang/String");
    gStringClassInfo.clazz = jclass(env->NewGlobalRef(clazz));



    return AndroidRuntime::registerNativeMethods(env, "android/database/sqlite/SQLiteConnection",
            sMethods, NELEM(sMethods));

}

} // namespace android






















>

>


>
>







 







>
>







 







|
|



|







|






|







 







|



|



|







 







>






>












|







 







>
|
>







 







|
|







 







>






>







 







>







 







>
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
>
|
>






|
|
|
>
|
>







 







>







 







|







 







>













>
>
|
|
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
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
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
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
...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
...
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
...
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
...
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931

#include <string.h>
#include <unistd.h>

#include <androidfw/CursorWindow.h>

#include <sqlite3.h>
#if 0
#include <sqlite3_android.h>
#endif

#include "android_database_SQLiteCommon.h"

#include <string>

// Set to 1 to use UTF16 storage for localized indexes.
#define UTF16_STORAGE 0

namespace android {

/* Busy timeout in milliseconds.
................................................................................
 * have a single open connection at a time unless they are using WAL.  When using
 * WAL, a timeout could occur if one connection is busy performing an auto-checkpoint
 * operation.  The busy timeout needs to be long enough to tolerate slow I/O write
 * operations but not so long as to cause the application to hang indefinitely if
 * there is a problem acquiring a database lock.
 */
static const int BUSY_TIMEOUT_MS = 2500;

static JavaVM *gpJavaVM = 0;

static struct {
    jfieldID name;
    jfieldID numArgs;
    jmethodID dispatchCallback;
} gSQLiteCustomFunctionClassInfo;

................................................................................
        OPEN_READ_MASK          = 0x00000001,
        NO_LOCALIZED_COLLATORS  = 0x00000010,
        CREATE_IF_NECESSARY     = 0x10000000,
    };

    sqlite3* const db;
    const int openFlags;
    std::string path;
    std::string label;

    volatile bool canceled;

    SQLiteConnection(sqlite3* db, int openFlags, const std::string& path, const std::string& label) :
        db(db), openFlags(openFlags), path(path), label(label), canceled(false) { }
};

// Called each time a statement begins execution, when tracing is enabled.
static void sqliteTraceCallback(void *data, const char *sql) {
    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
    ALOG(LOG_VERBOSE, SQLITE_TRACE_TAG, "%s: \"%s\"\n",
            connection->label.c_str(), sql);
}

// Called each time a statement finishes execution, when profiling is enabled.
static void sqliteProfileCallback(void *data, const char *sql, sqlite3_uint64 tm) {
    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
    ALOG(LOG_VERBOSE, SQLITE_PROFILE_TAG, "%s: \"%s\" took %0.3f ms\n",
            connection->label.c_str(), sql, tm * 0.000001f);
}

// Called after each SQLite VM instruction when cancelation is enabled.
static int sqliteProgressHandlerCallback(void* data) {
    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
    return connection->canceled;
}
................................................................................
    } else if (openFlags & SQLiteConnection::OPEN_READONLY) {
        sqliteFlags = SQLITE_OPEN_READONLY;
    } else {
        sqliteFlags = SQLITE_OPEN_READWRITE;
    }

    const char* pathChars = env->GetStringUTFChars(pathStr, NULL);
    std::string path(pathChars);
    env->ReleaseStringUTFChars(pathStr, pathChars);

    const char* labelChars = env->GetStringUTFChars(labelStr, NULL);
    std::string label(labelChars);
    env->ReleaseStringUTFChars(labelStr, labelChars);

    sqlite3* db;
    int err = sqlite3_open_v2(path.c_str(), &db, sqliteFlags, NULL);
    if (err != SQLITE_OK) {
        throw_sqlite3_exception_errcode(env, err, "Could not open database");
        return 0;
    }

    // Check that the database is really read/write when that is what we asked for.
    if ((sqliteFlags & SQLITE_OPEN_READWRITE) && sqlite3_db_readonly(db, NULL)) {
................................................................................
    if (err != SQLITE_OK) {
        throw_sqlite3_exception(env, db, "Could not set busy timeout");
        sqlite3_close(db);
        return 0;
    }

    // Register custom Android functions.
#if 0
    err = register_android_functions(db, UTF16_STORAGE);
    if (err) {
        throw_sqlite3_exception(env, db, "Could not register Android SQL functions.");
        sqlite3_close(db);
        return 0;
    }
#endif

    // Create wrapper object.
    SQLiteConnection* connection = new SQLiteConnection(db, openFlags, path, label);

    // Enable tracing and profiling if requested.
    if (enableTrace) {
        sqlite3_trace(db, &sqliteTraceCallback, connection);
    }
    if (enableProfile) {
        sqlite3_profile(db, &sqliteProfileCallback, connection);
    }

    ALOGV("Opened connection %p with label '%s'", db, label.c_str());
    return reinterpret_cast<jint>(connection);
}

static void nativeClose(JNIEnv* env, jclass clazz, jint connectionPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    if (connection) {
................................................................................
        delete connection;
    }
}

// Called each time a custom function is evaluated.
static void sqliteCustomFunctionCallback(sqlite3_context *context,
        int argc, sqlite3_value **argv) {

    JNIEnv* env = 0;
    gpJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4);

    // Get the callback function object.
    // Create a new local reference to it in case the callback tries to do something
    // dumb like unregister the function (thereby destroying the global ref) while it is running.
    jobject functionObjGlobal = reinterpret_cast<jobject>(sqlite3_user_data(context));
    jobject functionObj = env->NewLocalRef(functionObjGlobal);

................................................................................
        env->ExceptionClear();
    }
}

// Called when a custom function is destroyed.
static void sqliteCustomFunctionDestructor(void* data) {
    jobject functionObjGlobal = reinterpret_cast<jobject>(data);
    JNIEnv* env = 0;
    gpJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4);
    env->DeleteGlobalRef(functionObjGlobal);
}

static void nativeRegisterCustomFunction(JNIEnv* env, jclass clazz, jint connectionPtr,
        jobject functionObj) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

................................................................................
}

static void nativeRegisterLocalizedCollators(JNIEnv* env, jclass clazz, jint connectionPtr,
        jstring localeStr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    const char* locale = env->GetStringUTFChars(localeStr, NULL);
#if 0
    int err = register_localized_collators(connection->db, locale, UTF16_STORAGE);
    env->ReleaseStringUTFChars(localeStr, locale);

    if (err != SQLITE_OK) {
        throw_sqlite3_exception(env, connection->db);
    }
#endif
}

static jint nativePrepareStatement(JNIEnv* env, jclass clazz, jint connectionPtr,
        jstring sqlString) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    jsize sqlLength = env->GetStringLength(sqlString);
................................................................................
            return env->NewString(text, length);
        }
    }
    return NULL;
}

static int createAshmemRegionWithData(JNIEnv* env, const void* data, size_t length) {
#if 0
    int error = 0;
    int fd = ashmem_create_region(NULL, length);
    if (fd < 0) {
        error = errno;
        ALOGE("ashmem_create_region failed: %s", strerror(error));
    } else {
        if (length > 0) {
................................................................................
                return fd;
            }
        }

        close(fd);
    }

#endif
    jniThrowIOException(env, -1);
    return -1;
}

static jint nativeExecuteForBlobFileDescriptor(JNIEnv* env, jclass clazz,
        jint connectionPtr, jint statementPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
................................................................................

enum CopyRowResult {
    CPR_OK,
    CPR_FULL,
    CPR_ERROR,
};

static jlong nativeExecuteForCursorWindow(
  JNIEnv* env, jclass clazz,
  jint connectionPtr, 
  jint statementPtr, 
  jint windowPtr,
  jint startPos, 
  jint requiredPos, 
  jboolean countAllRows
) {
  jniThrowIOException(env, -1);
  return -1;
}

#if 0
static CopyRowResult copyRow(JNIEnv* env, CursorWindow* window,
        sqlite3_stmt* statement, int numColumns, int startPos, int addedRows) {
    // Allocate a new field directory for the row.
    status_t status = window->allocRow();
    if (status) {
        LOG_WINDOW("Failed allocating fieldDir at startPos %d row %d, error=%d",
                startPos, addedRows, status);
................................................................................
        jint startPos, jint requiredPos, jboolean countAllRows) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);

    status_t status = window->clear();
    if (status) {
        char *zMsg = sqlite3_mprintf(
            "Failed to clear the cursor window, status=%d", status
        );
        throw_sqlite3_exception(env, connection->db, zMsg);
        sqlite3_free(zMsg);
        return 0;
    }

    int numColumns = sqlite3_column_count(statement);
    status = window->setNumColumns(numColumns);
    if (status) {
        char *zMsg = sqlite3_mprintf(
            "Failed to set the cursor window column count to %d, status=%d",
            numColumns, status
        );
        throw_sqlite3_exception(env, connection->db, zMsg);
        sqlite3_free(zMsg);
        return 0;
    }

    int retryCount = 0;
    int totalRows = 0;
    int addedRows = 0;
    bool windowFull = false;
................................................................................
    // Report the total number of rows on request.
    if (startPos > totalRows) {
        ALOGE("startPos %d > actual rows %d", startPos, totalRows);
    }
    jlong result = jlong(startPos) << 32 | jlong(totalRows);
    return result;
}
#endif

static jint nativeGetDbLookaside(JNIEnv* env, jobject clazz, jint connectionPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    int cur = -1;
    int unused;
    sqlite3_db_status(connection->db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &unused, 0);
................................................................................
static JNINativeMethod sMethods[] =
{
    /* name, signature, funcPtr */
    { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)I",
            (void*)nativeOpen },
    { "nativeClose", "(I)V",
            (void*)nativeClose },
    { "nativeRegisterCustomFunction", "(ILorg/sqlite/database/sqlite/SQLiteCustomFunction;)V",
            (void*)nativeRegisterCustomFunction },
    { "nativeRegisterLocalizedCollators", "(ILjava/lang/String;)V",
            (void*)nativeRegisterLocalizedCollators },
    { "nativePrepareStatement", "(ILjava/lang/String;)I",
            (void*)nativePrepareStatement },
    { "nativeFinalizeStatement", "(II)V",
            (void*)nativeFinalizeStatement },
................................................................................

#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find field " fieldName);

int register_android_database_SQLiteConnection(JNIEnv *env)
{
#if 0
    jclass clazz;
    FIND_CLASS(clazz, "android/database/sqlite/SQLiteCustomFunction");

    GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.name, clazz,
            "name", "Ljava/lang/String;");
    GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.numArgs, clazz,
            "numArgs", "I");
    GET_METHOD_ID(gSQLiteCustomFunctionClassInfo.dispatchCallback,
            clazz, "dispatchCallback", "([Ljava/lang/String;)V");

    FIND_CLASS(clazz, "java/lang/String");
    gStringClassInfo.clazz = jclass(env->NewGlobalRef(clazz));

#endif
    return jniRegisterNativeMethods(env, 
        "org/sqlite/database/sqlite/SQLiteConnection",
        sMethods, NELEM(sMethods)
    );
}

} // namespace android

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
  JNIEnv *env = 0;

  __android_log_print(ANDROID_LOG_INFO,  __FUNCTION__, "Loaded custom SQLite");

  android::gpJavaVM = vm;
  vm->GetEnv((void**)&env, JNI_VERSION_1_4);
  android::register_android_database_SQLiteConnection(env);

  return JNI_VERSION_1_4;
}



Changes to jni/android_database_SQLiteDebug.cpp.

78
79
80
81
82
83
84
85
86
87
88
89
    GET_FIELD_ID(gSQLiteDebugPagerStatsClassInfo.memoryUsed, clazz,
            "memoryUsed", "I");
    GET_FIELD_ID(gSQLiteDebugPagerStatsClassInfo.largestMemAlloc, clazz,
            "largestMemAlloc", "I");
    GET_FIELD_ID(gSQLiteDebugPagerStatsClassInfo.pageCacheOverflow, clazz,
            "pageCacheOverflow", "I");

    return AndroidRuntime::registerNativeMethods(env, "android/database/sqlite/SQLiteDebug",
            gMethods, NELEM(gMethods));
}

} // namespace android







|




78
79
80
81
82
83
84
85
86
87
88
89
    GET_FIELD_ID(gSQLiteDebugPagerStatsClassInfo.memoryUsed, clazz,
            "memoryUsed", "I");
    GET_FIELD_ID(gSQLiteDebugPagerStatsClassInfo.largestMemAlloc, clazz,
            "largestMemAlloc", "I");
    GET_FIELD_ID(gSQLiteDebugPagerStatsClassInfo.pageCacheOverflow, clazz,
            "pageCacheOverflow", "I");

    return jniRegisterNativeMethods(env, "android/database/sqlite/SQLiteDebug",
            gMethods, NELEM(gMethods));
}

} // namespace android

Changes to jni/android_database_SQLiteGlobal.cpp.

17
18
19
20
21
22
23

24


25
26
27
28
29
30
31
..
51
52
53
54
55
56
57

58


59
60
61
62
63
64
65
..
78
79
80
81
82
83
84
85
86
87
88
89
#define LOG_TAG "SQLiteGlobal"

#include <jni.h>
#include <JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>

#include <sqlite3.h>

#include <sqlite3_android.h>



#include "android_database_SQLiteCommon.h"
#include "android_util_Log.h"

namespace android {

// Limit heap to 8MB for now.  This is 4 times the maximum cursor window
................................................................................
static void sqliteInitialize() {
    // Enable multi-threaded mode.  In this mode, SQLite is safe to use by multiple
    // threads as long as no two threads use the same database connection at the same
    // time (which we guarantee in the SQLite database wrappers).
    sqlite3_config(SQLITE_CONFIG_MULTITHREAD);

    // Redirect SQLite log messages to the Android log.

    bool verboseLog = android_util_Log_isVerboseLogEnabled(SQLITE_LOG_TAG);


    sqlite3_config(SQLITE_CONFIG_LOG, &sqliteLogCallback, verboseLog ? (void*)1 : NULL);

    // The soft heap limit prevents the page cache allocations from growing
    // beyond the given limit, no matter what the max page cache sizes are
    // set to. The limit does not, as of 3.5.0, affect any other allocations.
    sqlite3_soft_heap_limit(SOFT_HEAP_LIMIT);

................................................................................
            (void*)nativeReleaseMemory },
};

int register_android_database_SQLiteGlobal(JNIEnv *env)
{
    sqliteInitialize();

    return AndroidRuntime::registerNativeMethods(env, "android/database/sqlite/SQLiteGlobal",
            sMethods, NELEM(sMethods));
}

} // namespace android







>

>
>







 







>

>
>







 







|




17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
..
84
85
86
87
88
89
90
91
92
93
94
95
#define LOG_TAG "SQLiteGlobal"

#include <jni.h>
#include <JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>

#include <sqlite3.h>
#if 0
#include <sqlite3_android.h>
#endif


#include "android_database_SQLiteCommon.h"
#include "android_util_Log.h"

namespace android {

// Limit heap to 8MB for now.  This is 4 times the maximum cursor window
................................................................................
static void sqliteInitialize() {
    // Enable multi-threaded mode.  In this mode, SQLite is safe to use by multiple
    // threads as long as no two threads use the same database connection at the same
    // time (which we guarantee in the SQLite database wrappers).
    sqlite3_config(SQLITE_CONFIG_MULTITHREAD);

    // Redirect SQLite log messages to the Android log.
#if 0
    bool verboseLog = android_util_Log_isVerboseLogEnabled(SQLITE_LOG_TAG);
#endif
    bool verboseLog = false;
    sqlite3_config(SQLITE_CONFIG_LOG, &sqliteLogCallback, verboseLog ? (void*)1 : NULL);

    // The soft heap limit prevents the page cache allocations from growing
    // beyond the given limit, no matter what the max page cache sizes are
    // set to. The limit does not, as of 3.5.0, affect any other allocations.
    sqlite3_soft_heap_limit(SOFT_HEAP_LIMIT);

................................................................................
            (void*)nativeReleaseMemory },
};

int register_android_database_SQLiteGlobal(JNIEnv *env)
{
    sqliteInitialize();

    return jniRegisterNativeMethods(env, "android/database/sqlite/SQLiteGlobal",
            sMethods, NELEM(sMethods));
}

} // namespace android

Changes to src/org/sqlite/database/CharArrayBuffer.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database;

/**
 * This is used for {@link Cursor#copyStringToBuffer}
 */
public final class CharArrayBuffer {
    public CharArrayBuffer(int size) {
        data = new char[size];







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database;

/**
 * This is used for {@link Cursor#copyStringToBuffer}
 */
public final class CharArrayBuffer {
    public CharArrayBuffer(int size) {
        data = new char[size];

Changes to src/org/sqlite/database/DataSetObservable.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database;

/**
 * A specialization of {@link Observable} for {@link DataSetObserver}
 * that provides methods for sending notifications to a list of
 * {@link DataSetObserver} objects.
 */
public class DataSetObservable extends Observable<DataSetObserver> {







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database;

/**
 * A specialization of {@link Observable} for {@link DataSetObserver}
 * that provides methods for sending notifications to a list of
 * {@link DataSetObserver} objects.
 */
public class DataSetObservable extends Observable<DataSetObserver> {

Changes to src/org/sqlite/database/DataSetObserver.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database;

/**
 * Receives call backs when a data set has been changed, or made invalid. The typically data sets
 * that are observed are {@link Cursor}s or {@link android.widget.Adapter}s.
 * DataSetObserver must be implemented by objects which are added to a DataSetObservable.
 */
public abstract class DataSetObserver {







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database;

/**
 * Receives call backs when a data set has been changed, or made invalid. The typically data sets
 * that are observed are {@link Cursor}s or {@link android.widget.Adapter}s.
 * DataSetObserver must be implemented by objects which are added to a DataSetObservable.
 */
public abstract class DataSetObserver {

Changes to src/org/sqlite/database/DatabaseErrorHandler.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * 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 android.database;

import android.database.sqlite.SQLiteDatabase;

/**
 * An interface to let the apps define the actions to take when the following errors are detected
 *   database corruption
 */
public interface DatabaseErrorHandler {








|

|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * 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 org.sqlite.database;

import org.sqlite.database.sqlite.SQLiteDatabase;

/**
 * An interface to let the apps define the actions to take when the following errors are detected
 *   database corruption
 */
public interface DatabaseErrorHandler {

Changes to src/org/sqlite/database/DefaultDatabaseErrorHandler.java.

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
 *
 * 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 android.database;

import java.io.File;
import java.util.List;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
import android.util.Pair;

/**
 * Default class used to define the actions to take when the database corruption is reported
 * by sqlite.
 * <p>
 * An application can specify an implementation of {@link DatabaseErrorHandler} on the
 * following:
 * <ul>
 *   <li>{@link SQLiteDatabase#openOrCreateDatabase(String,
 *      android.database.sqlite.SQLiteDatabase.CursorFactory, DatabaseErrorHandler)}</li>
 *   <li>{@link SQLiteDatabase#openDatabase(String,
 *      android.database.sqlite.SQLiteDatabase.CursorFactory, int, DatabaseErrorHandler)}</li>
 * </ul>
 * The specified {@link DatabaseErrorHandler} is used to handle database corruption errors, if they
 * occur.
 * <p>
 * If null is specified for DatabaeErrorHandler param in the above calls, then this class is used
 * as the default {@link DatabaseErrorHandler}.
 */







|




|
|











|

|







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
 *
 * 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 org.sqlite.database;

import java.io.File;
import java.util.List;

import org.sqlite.database.sqlite.SQLiteDatabase;
import org.sqlite.database.sqlite.SQLiteException;
import android.util.Log;
import android.util.Pair;

/**
 * Default class used to define the actions to take when the database corruption is reported
 * by sqlite.
 * <p>
 * An application can specify an implementation of {@link DatabaseErrorHandler} on the
 * following:
 * <ul>
 *   <li>{@link SQLiteDatabase#openOrCreateDatabase(String,
 *      org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory, DatabaseErrorHandler)}</li>
 *   <li>{@link SQLiteDatabase#openDatabase(String,
 *      org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory, int, DatabaseErrorHandler)}</li>
 * </ul>
 * The specified {@link DatabaseErrorHandler} is used to handle database corruption errors, if they
 * occur.
 * <p>
 * If null is specified for DatabaeErrorHandler param in the above calls, then this class is used
 * as the default {@link DatabaseErrorHandler}.
 */

Changes to src/org/sqlite/database/IContentObserver.aidl.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
** 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 android.database;

import android.net.Uri;

/**
 * @hide
 */
interface IContentObserver







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
** 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 org.sqlite.database;

import android.net.Uri;

/**
 * @hide
 */
interface IContentObserver

Changes to src/org/sqlite/database/Observable.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database;

import java.util.ArrayList;

/**
 * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}.
 *
 * This abstract class is intended to be subclassed and specialized to maintain







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database;

import java.util.ArrayList;

/**
 * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}.
 *
 * This abstract class is intended to be subclassed and specialized to maintain

Changes to src/org/sqlite/database/SQLException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database;

/**
 * An exception that indicates there was an error with SQL parsing or execution.
 */
public class SQLException extends RuntimeException {
    public SQLException() {
    }







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database;

/**
 * An exception that indicates there was an error with SQL parsing or execution.
 */
public class SQLException extends RuntimeException {
    public SQLException() {
    }

Changes to src/org/sqlite/database/StaleDataException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database;

/**
 * This exception is thrown when a Cursor contains stale data and must be
 * requeried before being used again.
 */
public class StaleDataException extends java.lang.RuntimeException
{







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database;

/**
 * This exception is thrown when a Cursor contains stale data and must be
 * requeried before being used again.
 */
public class StaleDataException extends java.lang.RuntimeException
{

Changes to src/org/sqlite/database/sqlite/CloseGuard.java.

220
221
222
223
224
225
226
227
228
229
230
    }

    /**
     * Default Reporter which reports CloseGuard violations to the log.
     */
    private static final class DefaultReporter implements Reporter {
        @Override public void report (String message, Throwable allocationSite) {
            System.logW(message, allocationSite);
        }
    }
}







|



220
221
222
223
224
225
226
227
228
229
230
    }

    /**
     * Default Reporter which reports CloseGuard violations to the log.
     */
    private static final class DefaultReporter implements Reporter {
        @Override public void report (String message, Throwable allocationSite) {
            /* System.logW(message, allocationSite); */
        }
    }
}

Changes to src/org/sqlite/database/sqlite/DatabaseObjectNotClosedException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * An exception that indicates that garbage-collector is finalizing a database object
 * that is not explicitly closed
 * @hide
 */
public class DatabaseObjectNotClosedException extends RuntimeException {







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that garbage-collector is finalizing a database object
 * that is not explicitly closed
 * @hide
 */
public class DatabaseObjectNotClosedException extends RuntimeException {

Added src/org/sqlite/database/sqlite/ExtraUtils.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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * 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 org.sqlite.database;
import android.database.Cursor;
import android.database.CursorWindow;

/* import org.apache.commons.codec.binary.Hex; */

import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import org.sqlite.database.sqlite.SQLiteAbortException;
import org.sqlite.database.sqlite.SQLiteConstraintException;
import org.sqlite.database.sqlite.SQLiteDatabase;
import org.sqlite.database.sqlite.SQLiteDatabaseCorruptException;
import org.sqlite.database.sqlite.SQLiteDiskIOException;
import org.sqlite.database.sqlite.SQLiteException;
import org.sqlite.database.sqlite.SQLiteFullException;
import org.sqlite.database.sqlite.SQLiteProgram;
import org.sqlite.database.sqlite.SQLiteStatement;
import android.os.OperationCanceledException;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import android.util.Log;

import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.text.Collator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Static utility methods for dealing with databases and {@link Cursor}s.
 */
public class ExtraUtils {
    private static final String TAG = "ExtraUtils";

    private static final boolean DEBUG = false;

    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_SELECT = 1;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_UPDATE = 2;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_ATTACH = 3;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_BEGIN = 4;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_COMMIT = 5;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_ABORT = 6;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_PRAGMA = 7;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_DDL = 8;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_UNPREPARED = 9;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_OTHER = 99;

    /**
     * Returns column index of "_id" column, or -1 if not found.
     */
    public static int findRowIdColumnIndex(String[] columnNames) {
        int length = columnNames.length;
        for (int i = 0; i < length; i++) {
            if (columnNames[i].equals("_id")) {
                return i;
            }
        }
        return -1;
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteAbortException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * 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 android.database.sqlite;

/**
 * An exception that indicates that the SQLite program was aborted.
 * This can happen either through a call to ABORT in a trigger,
 * or as the result of using the ABORT conflict clause.
 */
public class SQLiteAbortException extends SQLiteException {
    public SQLiteAbortException() {}

    public SQLiteAbortException(String error) {
        super(error);
    }
}







|













10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that the SQLite program was aborted.
 * This can happen either through a call to ABORT in a trigger,
 * or as the result of using the ABORT conflict clause.
 */
public class SQLiteAbortException extends SQLiteException {
    public SQLiteAbortException() {}

    public SQLiteAbortException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteAccessPermException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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 android.database.sqlite;

/**
 * This exception class is used when sqlite can't access the database file
 * due to lack of permissions on the file.
 */
public class SQLiteAccessPermException extends SQLiteException {
    public SQLiteAccessPermException() {}

    public SQLiteAccessPermException(String error) {
        super(error);
    }
}







|












10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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 org.sqlite.database.sqlite;

/**
 * This exception class is used when sqlite can't access the database file
 * due to lack of permissions on the file.
 */
public class SQLiteAccessPermException extends SQLiteException {
    public SQLiteAccessPermException() {}

    public SQLiteAccessPermException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 android.database.sqlite;

/**
 * Thrown if the the bind or column parameter index is out of range
 */
public class SQLiteBindOrColumnIndexOutOfRangeException extends SQLiteException {
    public SQLiteBindOrColumnIndexOutOfRangeException() {}

    public SQLiteBindOrColumnIndexOutOfRangeException(String error) {
        super(error);
    }
}







|











10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 org.sqlite.database.sqlite;

/**
 * Thrown if the the bind or column parameter index is out of range
 */
public class SQLiteBindOrColumnIndexOutOfRangeException extends SQLiteException {
    public SQLiteBindOrColumnIndexOutOfRangeException() {}

    public SQLiteBindOrColumnIndexOutOfRangeException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteBlobTooBigException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 android.database.sqlite;

public class SQLiteBlobTooBigException extends SQLiteException {
    public SQLiteBlobTooBigException() {}

    public SQLiteBlobTooBigException(String error) {
        super(error);
    }
}







|








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 org.sqlite.database.sqlite;

public class SQLiteBlobTooBigException extends SQLiteException {
    public SQLiteBlobTooBigException() {}

    public SQLiteBlobTooBigException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteCantOpenDatabaseException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 android.database.sqlite;

public class SQLiteCantOpenDatabaseException extends SQLiteException {
    public SQLiteCantOpenDatabaseException() {}

    public SQLiteCantOpenDatabaseException(String error) {
        super(error);
    }
}







|








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 org.sqlite.database.sqlite;

public class SQLiteCantOpenDatabaseException extends SQLiteException {
    public SQLiteCantOpenDatabaseException() {}

    public SQLiteCantOpenDatabaseException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteClosable.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

import java.io.Closeable;

/**
 * An object created from a SQLiteDatabase that can be closed.
 *
 * This class implements a primitive reference counting scheme for database objects.







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

import java.io.Closeable;

/**
 * An object created from a SQLiteDatabase that can be closed.
 *
 * This class implements a primitive reference counting scheme for database objects.

Changes to src/org/sqlite/database/sqlite/SQLiteConnection.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
...
816
817
818
819
820
821
822

823
824
825
826
827
828
829
...
867
868
869
870
871
872
873


874
875
876
877
878
879
880
...
971
972
973
974
975
976
977















978
979
980
981
982
983
984
...
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
....
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
 * 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 android.database.sqlite;

import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;

import android.database.Cursor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.util.LruCache;
import android.util.Printer;

................................................................................
                & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
        boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);

        // Update configuration parameters.
        mConfiguration.updateParametersFrom(configuration);

        // Update prepared statement cache size.
        mPreparedStatementCache.resize(configuration.maxSqlCacheSize);

        // Update foreign key mode.
        if (foreignKeyModeChanged) {
            setForeignKeyModeFromConfiguration();
        }

        // Update WAL.
................................................................................
     * @throws SQLiteException if an error occurs, such as a syntax error
     * or invalid number of bind arguments.
     * @throws OperationCanceledException if the operation was canceled.
     */
    public int executeForCursorWindow(String sql, Object[] bindArgs,
            CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
            CancellationSignal cancellationSignal) {

        if (sql == null) {
            throw new IllegalArgumentException("sql must not be null.");
        }
        if (window == null) {
            throw new IllegalArgumentException("window must not be null.");
        }

................................................................................
                            + ", filledRows=" + filledRows
                            + ", countedRows=" + countedRows);
                }
            }
        } finally {
            window.releaseReference();
        }


    }

    private PreparedStatement acquirePreparedStatement(String sql) {
        PreparedStatement statement = mPreparedStatementCache.get(sql);
        boolean skipCache = false;
        if (statement != null) {
            if (!statement.mInUse) {
................................................................................
    // However, it will only be called between calls to attachCancellationSignal and
    // detachCancellationSignal, while a statement is executing.  We can safely assume
    // that the SQLite connection is still alive.
    @Override
    public void onCancel() {
        nativeCancel(mConnectionPtr);
    }
















    private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
        final int count = bindArgs != null ? bindArgs.length : 0;
        if (count != statement.mNumParameters) {
            throw new SQLiteBindOrColumnIndexOutOfRangeException(
                    "Expected " + statement.mNumParameters + " bind arguments but "
                    + count + " were provided.");
................................................................................
        if (count == 0) {
            return;
        }

        final int statementPtr = statement.mStatementPtr;
        for (int i = 0; i < count; i++) {
            final Object arg = bindArgs[i];
            switch (DatabaseUtils.getTypeOfObject(arg)) {
                case Cursor.FIELD_TYPE_NULL:
                    nativeBindNull(mConnectionPtr, statementPtr, i + 1);
                    break;
                case Cursor.FIELD_TYPE_INTEGER:
                    nativeBindLong(mConnectionPtr, statementPtr, i + 1,
                            ((Number)arg).longValue());
                    break;
................................................................................
                || statementType == DatabaseUtils.STATEMENT_SELECT) {
            return true;
        }
        return false;
    }

    private void applyBlockGuardPolicy(PreparedStatement statement) {
        if (!mConfiguration.isInMemoryDb()) {
            if (statement.mReadOnly) {
                BlockGuard.getThreadPolicy().onReadFromDisk();
            } else {
                BlockGuard.getThreadPolicy().onWriteToDisk();
            }
        }
    }

    /**
     * Dumps debugging information about this connection.
     *
     * @param printer The printer to receive the dump, not null.
     * @param verbose True to dump more verbose information.







|

|





|







 







|







 







>







 







>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|
|
|
|
|
|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
...
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
...
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
....
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
....
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
 * 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 org.sqlite.database.sqlite;

/* import dalvik.system.BlockGuard; */
import dalvik.system.CloseGuard;

import android.database.Cursor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import org.sqlite.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.util.LruCache;
import android.util.Printer;

................................................................................
                & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
        boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);

        // Update configuration parameters.
        mConfiguration.updateParametersFrom(configuration);

        // Update prepared statement cache size.
        /* mPreparedStatementCache.resize(configuration.maxSqlCacheSize); */

        // Update foreign key mode.
        if (foreignKeyModeChanged) {
            setForeignKeyModeFromConfiguration();
        }

        // Update WAL.
................................................................................
     * @throws SQLiteException if an error occurs, such as a syntax error
     * or invalid number of bind arguments.
     * @throws OperationCanceledException if the operation was canceled.
     */
    public int executeForCursorWindow(String sql, Object[] bindArgs,
            CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
            CancellationSignal cancellationSignal) {
      /*
        if (sql == null) {
            throw new IllegalArgumentException("sql must not be null.");
        }
        if (window == null) {
            throw new IllegalArgumentException("window must not be null.");
        }

................................................................................
                            + ", filledRows=" + filledRows
                            + ", countedRows=" + countedRows);
                }
            }
        } finally {
            window.releaseReference();
        }
   */
      return -1;
    }

    private PreparedStatement acquirePreparedStatement(String sql) {
        PreparedStatement statement = mPreparedStatementCache.get(sql);
        boolean skipCache = false;
        if (statement != null) {
            if (!statement.mInUse) {
................................................................................
    // However, it will only be called between calls to attachCancellationSignal and
    // detachCancellationSignal, while a statement is executing.  We can safely assume
    // that the SQLite connection is still alive.
    @Override
    public void onCancel() {
        nativeCancel(mConnectionPtr);
    }

    private static int databaseutils_getTypeOfObject(Object obj) {
        if (obj == null) {
            return Cursor.FIELD_TYPE_NULL;
        } else if (obj instanceof byte[]) {
            return Cursor.FIELD_TYPE_BLOB;
        } else if (obj instanceof Float || obj instanceof Double) {
            return Cursor.FIELD_TYPE_FLOAT;
        } else if (obj instanceof Long || obj instanceof Integer
                || obj instanceof Short || obj instanceof Byte) {
            return Cursor.FIELD_TYPE_INTEGER;
        } else {
            return Cursor.FIELD_TYPE_STRING;
        }
    }

    private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
        final int count = bindArgs != null ? bindArgs.length : 0;
        if (count != statement.mNumParameters) {
            throw new SQLiteBindOrColumnIndexOutOfRangeException(
                    "Expected " + statement.mNumParameters + " bind arguments but "
                    + count + " were provided.");
................................................................................
        if (count == 0) {
            return;
        }

        final int statementPtr = statement.mStatementPtr;
        for (int i = 0; i < count; i++) {
            final Object arg = bindArgs[i];
            switch (databaseutils_getTypeOfObject(arg)) {
                case Cursor.FIELD_TYPE_NULL:
                    nativeBindNull(mConnectionPtr, statementPtr, i + 1);
                    break;
                case Cursor.FIELD_TYPE_INTEGER:
                    nativeBindLong(mConnectionPtr, statementPtr, i + 1,
                            ((Number)arg).longValue());
                    break;
................................................................................
                || statementType == DatabaseUtils.STATEMENT_SELECT) {
            return true;
        }
        return false;
    }

    private void applyBlockGuardPolicy(PreparedStatement statement) {
/*        if (!mConfiguration.isInMemoryDb()) {*/
/*            if (statement.mReadOnly) {*/
/*                BlockGuard.getThreadPolicy().onReadFromDisk();*/
/*            } else {*/
/*                BlockGuard.getThreadPolicy().onWriteToDisk();*/
/*            }*/
/*        }*/
    }

    /**
     * Dumps debugging information about this connection.
     *
     * @param printer The printer to receive the dump, not null.
     * @param verbose True to dump more verbose information.

Changes to src/org/sqlite/database/sqlite/SQLiteConnectionPool.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
1009
....
1046
1047
1048
1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059
 * 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 android.database.sqlite;

import dalvik.system.CloseGuard;

import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.SystemClock;
import android.util.Log;
import android.util.PrefixPrinter;
import android.util.Printer;

import java.io.Closeable;
import java.util.ArrayList;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
................................................................................
    /**
     * Dumps debugging information about this connection pool.
     *
     * @param printer The printer to receive the dump, not null.
     * @param verbose True to dump more verbose information.
     */
    public void dump(Printer printer, boolean verbose) {

        Printer indentedPrinter = PrefixPrinter.create(printer, "    ");
        synchronized (mLock) {
            printer.println("Connection pool for " + mConfiguration.path + ":");
            printer.println("  Open: " + mIsOpen);
            printer.println("  Max connections: " + mMaxConnectionPoolSize);

            printer.println("  Available primary connection:");
            if (mAvailablePrimaryConnection != null) {
................................................................................
                            + ", priority=" + waiter.mPriority
                            + ", sql='" + waiter.mSql + "'");
                }
            } else {
                indentedPrinter.println("<none>");
            }
        }

    }

    @Override
    public String toString() {
        return "SQLiteConnectionPool: " + mConfiguration.path;
    }








|



|




|







 







>
|







 







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
....
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
 * 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 org.sqlite.database.sqlite;

import dalvik.system.CloseGuard;

import org.sqlite.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.SystemClock;
import android.util.Log;
/* import android.util.PrefixPrinter; */
import android.util.Printer;

import java.io.Closeable;
import java.util.ArrayList;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
................................................................................
    /**
     * Dumps debugging information about this connection pool.
     *
     * @param printer The printer to receive the dump, not null.
     * @param verbose True to dump more verbose information.
     */
    public void dump(Printer printer, boolean verbose) {
      /*
        Printer indentedPrinter = Printer.create(printer, "    ");
        synchronized (mLock) {
            printer.println("Connection pool for " + mConfiguration.path + ":");
            printer.println("  Open: " + mIsOpen);
            printer.println("  Max connections: " + mMaxConnectionPoolSize);

            printer.println("  Available primary connection:");
            if (mAvailablePrimaryConnection != null) {
................................................................................
                            + ", priority=" + waiter.mPriority
                            + ", sql='" + waiter.mSql + "'");
                }
            } else {
                indentedPrinter.println("<none>");
            }
        }
        */
    }

    @Override
    public String toString() {
        return "SQLiteConnectionPool: " + mConfiguration.path;
    }

Changes to src/org/sqlite/database/sqlite/SQLiteConstraintException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 android.database.sqlite;

/**
 * An exception that indicates that an integrity constraint was violated.
 */
public class SQLiteConstraintException extends SQLiteException {
    public SQLiteConstraintException() {}

    public SQLiteConstraintException(String error) {
        super(error);
    }
}







|











10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that an integrity constraint was violated.
 */
public class SQLiteConstraintException extends SQLiteException {
    public SQLiteConstraintException() {}

    public SQLiteConstraintException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteCursor.java.

10
11
12
13
14
15
16
17


18
19
20

21
22
23
24
25
26
27
..
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
...
132
133
134
135
136
137
138

139
140
141
142
143
144
145
...
155
156
157
158
159
160
161

162
163
164
165
166
167
168
...
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
 * 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 android.database.sqlite;



import android.database.AbstractWindowedCursor;
import android.database.CursorWindow;

import android.database.DatabaseUtils;
import android.os.StrictMode;
import android.util.Log;

import java.util.HashMap;
import java.util.Map;

................................................................................
     * @param editTable the name of the table used for this query
     * @param query the {@link SQLiteQuery} object associated with this cursor object.
     */
    public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {
        if (query == null) {
            throw new IllegalArgumentException("query object cannot be null");
        }
        if (StrictMode.vmSqliteObjectLeaksEnabled()) {
            mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
        } else {
            mStackTrace = null;
        }
        mDriver = driver;
        mEditTable = editTable;
        mColumnNameMap = null;
        mQuery = query;

        mColumns = query.getColumnNames();
        mRowIdColumnIndex = DatabaseUtils.findRowIdColumnIndex(mColumns);
    }

    /**
     * Get the database that this cursor is associated with.
     * @return the SQLiteDatabase that this cursor is associated with.
     */
    public SQLiteDatabase getDatabase() {
................................................................................
        if (mCount == NO_COUNT) {
            fillWindow(0);
        }
        return mCount;
    }

    private void fillWindow(int requiredPos) {

        clearOrCreateWindow(getDatabase().getPath());

        try {
            if (mCount == NO_COUNT) {
                int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0);
                mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true);
                mCursorWindowCapacity = mWindow.getNumRows();
................................................................................
            // Close the cursor window if the query failed and therefore will
            // not produce any results.  This helps to avoid accidentally leaking
            // the cursor window if the client does not correctly handle exceptions
            // and fails to close the cursor.
            closeWindow();
            throw ex;
        }

    }

    @Override
    public int getColumnIndex(String columnName) {
        // Create mColumnNameMap on demand
        if (mColumnNameMap == null) {
            String[] columns = mColumns;
................................................................................
     * Release the native resources, if they haven't been released yet.
     */
    @Override
    protected void finalize() {
        try {
            // if the cursor hasn't been closed yet, close it first
            if (mWindow != null) {

                if (mStackTrace != null) {
                    String sql = mQuery.getSql();
                    int len = sql.length();
                    StrictMode.onSqliteObjectLeaked(
                        "Finalizing a Cursor that has not been deactivated or closed. " +
                        "database = " + mQuery.getDatabase().getLabel() +
                        ", table = " + mEditTable +
                        ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
                        mStackTrace);
                }

                close();
            }
        } finally {
            super.finalize();
        }
    }
}







|
>
>



>







 







|










|







 







>







 







>







 







>










>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
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
...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
 * 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 org.sqlite.database.sqlite;

import org.sqlite.database.ExtraUtils;

import android.database.AbstractWindowedCursor;
import android.database.CursorWindow;

import android.database.DatabaseUtils;
import android.os.StrictMode;
import android.util.Log;

import java.util.HashMap;
import java.util.Map;

................................................................................
     * @param editTable the name of the table used for this query
     * @param query the {@link SQLiteQuery} object associated with this cursor object.
     */
    public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {
        if (query == null) {
            throw new IllegalArgumentException("query object cannot be null");
        }
        if (/* StrictMode.vmSqliteObjectLeaksEnabled() */ false ) {
            mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
        } else {
            mStackTrace = null;
        }
        mDriver = driver;
        mEditTable = editTable;
        mColumnNameMap = null;
        mQuery = query;

        mColumns = query.getColumnNames();
        mRowIdColumnIndex = ExtraUtils.findRowIdColumnIndex(mColumns);
    }

    /**
     * Get the database that this cursor is associated with.
     * @return the SQLiteDatabase that this cursor is associated with.
     */
    public SQLiteDatabase getDatabase() {
................................................................................
        if (mCount == NO_COUNT) {
            fillWindow(0);
        }
        return mCount;
    }

    private void fillWindow(int requiredPos) {
      /*
        clearOrCreateWindow(getDatabase().getPath());

        try {
            if (mCount == NO_COUNT) {
                int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0);
                mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true);
                mCursorWindowCapacity = mWindow.getNumRows();
................................................................................
            // Close the cursor window if the query failed and therefore will
            // not produce any results.  This helps to avoid accidentally leaking
            // the cursor window if the client does not correctly handle exceptions
            // and fails to close the cursor.
            closeWindow();
            throw ex;
        }
        */
    }

    @Override
    public int getColumnIndex(String columnName) {
        // Create mColumnNameMap on demand
        if (mColumnNameMap == null) {
            String[] columns = mColumns;
................................................................................
     * Release the native resources, if they haven't been released yet.
     */
    @Override
    protected void finalize() {
        try {
            // if the cursor hasn't been closed yet, close it first
            if (mWindow != null) {
                    /*
                if (mStackTrace != null) {
                    String sql = mQuery.getSql();
                    int len = sql.length();
                    StrictMode.onSqliteObjectLeaked(
                        "Finalizing a Cursor that has not been deactivated or closed. " +
                        "database = " + mQuery.getDatabase().getLabel() +
                        ", table = " + mEditTable +
                        ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
                        mStackTrace);
                }
                */
                close();
            }
        } finally {
            super.finalize();
        }
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteCursorDriver.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 android.database.sqlite;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase.CursorFactory;

/**
 * A driver for SQLiteCursors that is used to create them and gets notified
 * by the cursors it creates on significant events in their lifetimes.
 */
public interface SQLiteCursorDriver {
    /**







|


|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 org.sqlite.database.sqlite;

import android.database.Cursor;
import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory;

/**
 * A driver for SQLiteCursors that is used to create them and gets notified
 * by the cursors it creates on significant events in their lifetimes.
 */
public interface SQLiteCursorDriver {
    /**

Changes to src/org/sqlite/database/sqlite/SQLiteCustomFunction.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * Describes a custom SQL function.
 *
 * @hide
 */
public final class SQLiteCustomFunction {







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * Describes a custom SQL function.
 *
 * @hide
 */
public final class SQLiteCustomFunction {

Changes to src/org/sqlite/database/sqlite/SQLiteDatabase.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
848
849
850
851
852
853
854


























855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
...
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
...
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
 * 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 android.database.sqlite;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.DatabaseUtils;
import android.database.DefaultDatabaseErrorHandler;
import android.database.SQLException;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.Looper;
import android.os.OperationCanceledException;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
................................................................................
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.customFunctions.remove(wrapper);
                throw ex;
            }
        }
    }



























    /**
     * Gets the database version.
     *
     * @return the database version
     */
    public int getVersion() {
        return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
    }

    /**
     * Sets the database version.
     *
     * @param version the new database version
     */
................................................................................

    /**
     * Returns the maximum size the database may grow to.
     *
     * @return the new maximum database size
     */
    public long getMaximumSize() {
        long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
        return pageCount * getPageSize();
    }

    /**
     * Sets the maximum size the database will grow to. The maximum size cannot
     * be set below the current size.
     *
................................................................................
    public long setMaximumSize(long numBytes) {
        long pageSize = getPageSize();
        long numPages = numBytes / pageSize;
        // If numBytes isn't a multiple of pageSize, bump up a page
        if ((numBytes % pageSize) != 0) {
            numPages++;
        }
        long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
                null);
        return newPageCount * pageSize;
    }

    /**
     * Returns the current database page size, in bytes.
     *
     * @return the database page size, in bytes
     */
    public long getPageSize() {
        return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
    }

    /**
     * Sets the database page size. The page size must be a power of two. This
     * method does not work if any data has been written to the database file,
     * and must be called right after the database has been created.
     *







|



|

|
|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|







 







|







 







|










|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
848
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
887
888
889
890
891
892
893
894
895
...
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
...
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
 * 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 org.sqlite.database.sqlite;

import android.content.ContentValues;
import android.database.Cursor;
import org.sqlite.database.DatabaseErrorHandler;
import android.database.DatabaseUtils;
import org.sqlite.database.DefaultDatabaseErrorHandler;
import org.sqlite.database.SQLException;
import org.sqlite.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.Looper;
import android.os.OperationCanceledException;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
................................................................................
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.customFunctions.remove(wrapper);
                throw ex;
            }
        }
    }

    /**
     * Utility method to run the query on the db and return the value in the
     * first column of the first row.
     */
    private static long databaseutils_longForQuery(
        SQLiteDatabase db, String query, String[] selectionArgs
    ) {
        SQLiteStatement prog = db.compileStatement(query);
        try {
            return databaseutils_longForQuery(prog, selectionArgs);
        } finally {
            prog.close();
        }
    }

    /**
     * Utility method to run the pre-compiled query and return the value in the
     * first column of the first row.
     */
    private static long databaseutils_longForQuery(
        SQLiteStatement prog, String[] selectionArgs
    ) {
        prog.bindAllArgsAsStrings(selectionArgs);
        return prog.simpleQueryForLong();
    }

    /**
     * Gets the database version.
     *
     * @return the database version
     */
    public int getVersion() {
        return ((Long) databaseutils_longForQuery(this, "PRAGMA user_version;", null)).intValue();
    }

    /**
     * Sets the database version.
     *
     * @param version the new database version
     */
................................................................................

    /**
     * Returns the maximum size the database may grow to.
     *
     * @return the new maximum database size
     */
    public long getMaximumSize() {
        long pageCount = databaseutils_longForQuery(this, "PRAGMA max_page_count;", null);
        return pageCount * getPageSize();
    }

    /**
     * Sets the maximum size the database will grow to. The maximum size cannot
     * be set below the current size.
     *
................................................................................
    public long setMaximumSize(long numBytes) {
        long pageSize = getPageSize();
        long numPages = numBytes / pageSize;
        // If numBytes isn't a multiple of pageSize, bump up a page
        if ((numBytes % pageSize) != 0) {
            numPages++;
        }
        long newPageCount = databaseutils_longForQuery(this, "PRAGMA max_page_count = " + numPages,
                null);
        return newPageCount * pageSize;
    }

    /**
     * Returns the current database page size, in bytes.
     *
     * @return the database page size, in bytes
     */
    public long getPageSize() {
        return databaseutils_longForQuery(this, "PRAGMA page_size;", null);
    }

    /**
     * Sets the database page size. The page size must be a power of two. This
     * method does not work if any data has been written to the database file,
     * and must be called right after the database has been created.
     *

Changes to src/org/sqlite/database/sqlite/SQLiteDatabaseConfiguration.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

import java.util.ArrayList;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * Describes how to configure a database.







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

import java.util.ArrayList;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * Describes how to configure a database.

Changes to src/org/sqlite/database/sqlite/SQLiteDatabaseCorruptException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 android.database.sqlite;

/**
 * An exception that indicates that the SQLite database file is corrupt.
 */
public class SQLiteDatabaseCorruptException extends SQLiteException {
    public SQLiteDatabaseCorruptException() {}

    public SQLiteDatabaseCorruptException(String error) {
        super(error);
    }
}







|











10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that the SQLite database file is corrupt.
 */
public class SQLiteDatabaseCorruptException extends SQLiteException {
    public SQLiteDatabaseCorruptException() {}

    public SQLiteDatabaseCorruptException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteDatabaseLockedException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * Thrown if  the database engine was unable to acquire the
 * database locks it needs to do its job.  If the statement is a [COMMIT]
 * or occurs outside of an explicit transaction, then you can retry the
 * statement.  If the statement is not a [COMMIT] and occurs within a
 * explicit transaction then you should rollback the transaction before







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * Thrown if  the database engine was unable to acquire the
 * database locks it needs to do its job.  If the statement is a [COMMIT]
 * or occurs outside of an explicit transaction, then you can retry the
 * statement.  If the statement is not a [COMMIT] and occurs within a
 * explicit transaction then you should rollback the transaction before

Changes to src/org/sqlite/database/sqlite/SQLiteDatatypeMismatchException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 android.database.sqlite;

public class SQLiteDatatypeMismatchException extends SQLiteException {
    public SQLiteDatatypeMismatchException() {}

    public SQLiteDatatypeMismatchException(String error) {
        super(error);
    }
}







|








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 org.sqlite.database.sqlite;

public class SQLiteDatatypeMismatchException extends SQLiteException {
    public SQLiteDatatypeMismatchException() {}

    public SQLiteDatatypeMismatchException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteDebug.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 * 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 android.database.sqlite;

import java.util.ArrayList;

import android.os.Build;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Printer;

/**
 * Provides debugging info about all SQLite databases running in the current process.
 *
 * {@hide}
................................................................................
    public static final boolean DEBUG_SQL_TIME =
            Log.isLoggable("SQLiteTime", Log.VERBOSE);

    /**
     * True to enable database performance testing instrumentation.
     * @hide
     */
    public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;

    private SQLiteDebug() {
    }

    /**
     * Determines whether a query should be logged.
     *
................................................................................
     *
     * This value can be changed dynamically while the system is running.
     * For example, "adb shell setprop db.log.slow_query_threshold 200" will
     * log all queries that take 200ms or longer to run.
     * @hide
     */
    public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) {
        int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1);
        return slowQueryMillis >= 0 && elapsedTimeMillis >= slowQueryMillis;
    }

    /**
     * Contains statistics about the active pagers in the current process.
     *
     * @see #nativeGetPagerStats(PagerStats)







|




|







 







|







 







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 * 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 org.sqlite.database.sqlite;

import java.util.ArrayList;

import android.os.Build;
/* import android.os.SystemProperties; */
import android.util.Log;
import android.util.Printer;

/**
 * Provides debugging info about all SQLite databases running in the current process.
 *
 * {@hide}
................................................................................
    public static final boolean DEBUG_SQL_TIME =
            Log.isLoggable("SQLiteTime", Log.VERBOSE);

    /**
     * True to enable database performance testing instrumentation.
     * @hide
     */
    public static final boolean DEBUG_LOG_SLOW_QUERIES = false;

    private SQLiteDebug() {
    }

    /**
     * Determines whether a query should be logged.
     *
................................................................................
     *
     * This value can be changed dynamically while the system is running.
     * For example, "adb shell setprop db.log.slow_query_threshold 200" will
     * log all queries that take 200ms or longer to run.
     * @hide
     */
    public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) {
        int slowQueryMillis = 10000;
        return slowQueryMillis >= 0 && elapsedTimeMillis >= slowQueryMillis;
    }

    /**
     * Contains statistics about the active pagers in the current process.
     *
     * @see #nativeGetPagerStats(PagerStats)

Changes to src/org/sqlite/database/sqlite/SQLiteDirectCursorDriver.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 android.database.sqlite;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.CancellationSignal;

/**
 * A cursor driver that uses the given query directly.
 * 
 * @hide
 */







|


|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * 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 org.sqlite.database.sqlite;

import android.database.Cursor;
import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.CancellationSignal;

/**
 * A cursor driver that uses the given query directly.
 * 
 * @hide
 */

Changes to src/org/sqlite/database/sqlite/SQLiteDiskIOException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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 android.database.sqlite;

/**
 * An exception that indicates that an IO error occured while accessing the 
 * SQLite database file.
 */
public class SQLiteDiskIOException extends SQLiteException {
    public SQLiteDiskIOException() {}

    public SQLiteDiskIOException(String error) {
        super(error);
    }
}







|












10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that an IO error occured while accessing the 
 * SQLite database file.
 */
public class SQLiteDiskIOException extends SQLiteException {
    public SQLiteDiskIOException() {}

    public SQLiteDiskIOException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteDoneException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * An exception that indicates that the SQLite program is done.
 * Thrown when an operation that expects a row (such as {@link
 * SQLiteStatement#simpleQueryForString} or {@link
 * SQLiteStatement#simpleQueryForLong}) does not get one.
 */







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that the SQLite program is done.
 * Thrown when an operation that expects a row (such as {@link
 * SQLiteStatement#simpleQueryForString} or {@link
 * SQLiteStatement#simpleQueryForLong}) does not get one.
 */

Changes to src/org/sqlite/database/sqlite/SQLiteException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * 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 android.database.sqlite;

import android.database.SQLException;

/**
 * A SQLite exception that indicates there was an error with SQL parsing or execution.
 */
public class SQLiteException extends SQLException {
    public SQLiteException() {
    }







|

|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * 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 org.sqlite.database.sqlite;

import org.sqlite.database.SQLException;

/**
 * A SQLite exception that indicates there was an error with SQL parsing or execution.
 */
public class SQLiteException extends SQLException {
    public SQLiteException() {
    }

Changes to src/org/sqlite/database/sqlite/SQLiteFullException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 android.database.sqlite;

/**
 * An exception that indicates that the SQLite database is full.
 */
public class SQLiteFullException extends SQLiteException {
    public SQLiteFullException() {}

    public SQLiteFullException(String error) {
        super(error);
    }
}







|











10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * 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 org.sqlite.database.sqlite;

/**
 * An exception that indicates that the SQLite database is full.
 */
public class SQLiteFullException extends SQLiteException {
    public SQLiteFullException() {}

    public SQLiteFullException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteGlobal.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
 * 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 android.database.sqlite;

import android.content.res.Resources;
import android.os.StatFs;
import android.os.SystemProperties;

/**
 * Provides access to SQLite functions that affect all database connection,
 * such as memory management.
 *
 * The native code associated with SQLiteGlobal is also sets global configuration options
 * using sqlite3_config() then calls sqlite3_initialize() to ensure that the SQLite
................................................................................
     * Gets the default page size to use when creating a database.
     */
    public static int getDefaultPageSize() {
        synchronized (sLock) {
            if (sDefaultPageSize == 0) {
                sDefaultPageSize = new StatFs("/data").getBlockSize();
            }
            return SystemProperties.getInt("debug.sqlite.pagesize", sDefaultPageSize);
        }
    }

    /**
     * Gets the default journal mode when WAL is not in use.
     */
    public static String getDefaultJournalMode() {
        return SystemProperties.get("debug.sqlite.journalmode",
                Resources.getSystem().getString(
                com.android.internal.R.string.db_default_journal_mode));
    }

    /**
     * Gets the journal size limit in bytes.
     */
    public static int getJournalSizeLimit() {
        return SystemProperties.getInt("debug.sqlite.journalsizelimit",
                Resources.getSystem().getInteger(
                com.android.internal.R.integer.db_journal_size_limit));
    }

    /**
     * Gets the default database synchronization mode when WAL is not in use.
     */
    public static String getDefaultSyncMode() {
        return SystemProperties.get("debug.sqlite.syncmode",
                Resources.getSystem().getString(
                com.android.internal.R.string.db_default_sync_mode));
    }

    /**
     * Gets the database synchronization mode when in WAL mode.
     */
    public static String getWALSyncMode() {
        return SystemProperties.get("debug.sqlite.wal.syncmode",
                Resources.getSystem().getString(
                com.android.internal.R.string.db_wal_sync_mode));
    }

    /**
     * Gets the WAL auto-checkpoint integer in database pages.
     */
    public static int getWALAutoCheckpoint() {
        int value = SystemProperties.getInt("debug.sqlite.wal.autocheckpoint",
                Resources.getSystem().getInteger(
                com.android.internal.R.integer.db_wal_autocheckpoint));
        return Math.max(1, value);
    }

    /**
     * Gets the connection pool size when in WAL mode.
     */
    public static int getWALConnectionPoolSize() {
        int value = SystemProperties.getInt("debug.sqlite.wal.poolsize",
                Resources.getSystem().getInteger(
                com.android.internal.R.integer.db_connection_pool_size));
        return Math.max(2, value);
    }
}







|



|







 







|







|
<
<






|
<
<






|
<
<






|
<
<






|
<
<







|
<
<



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
 * 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 org.sqlite.database.sqlite;

import android.content.res.Resources;
import android.os.StatFs;
/* import android.os.SystemProperties; */

/**
 * Provides access to SQLite functions that affect all database connection,
 * such as memory management.
 *
 * The native code associated with SQLiteGlobal is also sets global configuration options
 * using sqlite3_config() then calls sqlite3_initialize() to ensure that the SQLite
................................................................................
     * Gets the default page size to use when creating a database.
     */
    public static int getDefaultPageSize() {
        synchronized (sLock) {
            if (sDefaultPageSize == 0) {
                sDefaultPageSize = new StatFs("/data").getBlockSize();
            }
            return 1024;
        }
    }

    /**
     * Gets the default journal mode when WAL is not in use.
     */
    public static String getDefaultJournalMode() {
        return "delete";


    }

    /**
     * Gets the journal size limit in bytes.
     */
    public static int getJournalSizeLimit() {
        return 10000;


    }

    /**
     * Gets the default database synchronization mode when WAL is not in use.
     */
    public static String getDefaultSyncMode() {
        return "normal";


    }

    /**
     * Gets the database synchronization mode when in WAL mode.
     */
    public static String getWALSyncMode() {
        return "normal";


    }

    /**
     * Gets the WAL auto-checkpoint integer in database pages.
     */
    public static int getWALAutoCheckpoint() {
        int value = 1000;


        return Math.max(1, value);
    }

    /**
     * Gets the connection pool size when in WAL mode.
     */
    public static int getWALConnectionPoolSize() {
        int value = 10;


        return Math.max(2, value);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteMisuseException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * This error can occur if the application creates a SQLiteStatement object and allows multiple
 * threads in the application use it at the same time.
 * Sqlite returns this error if bind and execute methods on this object occur at the same time
 * from multiple threads, like so:
 *     thread # 1: in execute() method of the SQLiteStatement object







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * This error can occur if the application creates a SQLiteStatement object and allows multiple
 * threads in the application use it at the same time.
 * Sqlite returns this error if bind and execute methods on this object occur at the same time
 * from multiple threads, like so:
 *     thread # 1: in execute() method of the SQLiteStatement object

Changes to src/org/sqlite/database/sqlite/SQLiteOpenHelper.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
 * 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 android.database.sqlite;

import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.DefaultDatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;

/**
 * A helper class to manage database creation and version management.
 *
 * <p>You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
 * optionally {@link #onOpen}, and this class takes care of opening the database
................................................................................
            } else {
                try {
                    if (DEBUG_STRICT_READONLY && !writable) {
                        final String path = mContext.getDatabasePath(mName).getPath();
                        db = SQLiteDatabase.openDatabase(path, mFactory,
                                SQLiteDatabase.OPEN_READONLY, mErrorHandler);
                    } else {
                        db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
                                Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
                                mFactory, mErrorHandler);
                    }
                } catch (SQLiteException ex) {
                    if (writable) {
                        throw ex;
                    }
                    Log.e(TAG, "Couldn't open " + mName
                            + " for writing (will try read-only):", ex);







|


|
|
|







 







|
|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
 * 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 org.sqlite.database.sqlite;

import android.content.Context;
import org.sqlite.database.DatabaseErrorHandler;
import org.sqlite.database.DefaultDatabaseErrorHandler;
import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;

/**
 * A helper class to manage database creation and version management.
 *
 * <p>You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
 * optionally {@link #onOpen}, and this class takes care of opening the database
................................................................................
            } else {
                try {
                    if (DEBUG_STRICT_READONLY && !writable) {
                        final String path = mContext.getDatabasePath(mName).getPath();
                        db = SQLiteDatabase.openDatabase(path, mFactory,
                                SQLiteDatabase.OPEN_READONLY, mErrorHandler);
                    } else {
                        db = SQLiteDatabase.openOrCreateDatabase(
                                mName, mFactory, mErrorHandler
                        );
                    }
                } catch (SQLiteException ex) {
                    if (writable) {
                        throw ex;
                    }
                    Log.e(TAG, "Couldn't open " + mName
                            + " for writing (will try read-only):", ex);

Changes to src/org/sqlite/database/sqlite/SQLiteOutOfMemoryException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 android.database.sqlite;

public class SQLiteOutOfMemoryException extends SQLiteException {
    public SQLiteOutOfMemoryException() {}

    public SQLiteOutOfMemoryException(String error) {
        super(error);
    }
}







|








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 org.sqlite.database.sqlite;

public class SQLiteOutOfMemoryException extends SQLiteException {
    public SQLiteOutOfMemoryException() {}

    public SQLiteOutOfMemoryException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteProgram.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

import android.database.DatabaseUtils;
import android.os.CancellationSignal;

import java.util.Arrays;

/**







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

import android.database.DatabaseUtils;
import android.os.CancellationSignal;

import java.util.Arrays;

/**

Changes to src/org/sqlite/database/sqlite/SQLiteQuery.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

import android.database.CursorWindow;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.util.Log;

/**







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

import android.database.CursorWindow;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.util.Log;

/**

Changes to src/org/sqlite/database/sqlite/SQLiteQueryBuilder.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

import android.database.Cursor;
import android.database.DatabaseUtils;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.provider.BaseColumns;
import android.text.TextUtils;







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

import android.database.Cursor;
import android.database.DatabaseUtils;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.provider.BaseColumns;
import android.text.TextUtils;

Changes to src/org/sqlite/database/sqlite/SQLiteReadOnlyDatabaseException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 android.database.sqlite;

public class SQLiteReadOnlyDatabaseException extends SQLiteException {
    public SQLiteReadOnlyDatabaseException() {}

    public SQLiteReadOnlyDatabaseException(String error) {
        super(error);
    }
}







|








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 org.sqlite.database.sqlite;

public class SQLiteReadOnlyDatabaseException extends SQLiteException {
    public SQLiteReadOnlyDatabaseException() {}

    public SQLiteReadOnlyDatabaseException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteSession.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;








|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;

Changes to src/org/sqlite/database/sqlite/SQLiteStatement.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
 * 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 android.database.sqlite;

import android.os.ParcelFileDescriptor;

/**
 * Represents a statement that can be executed against a database.  The statement
 * cannot return multiple rows or columns, but single value (1 x 1) result sets
 * are supported.
................................................................................
        super(db, sql, bindArgs, null);
    }

    /**
     * Execute this SQL statement, if it is not a SELECT / INSERT / DELETE / UPDATE, for example
     * CREATE / DROP table, view, trigger, index etc.
     *
     * @throws android.database.SQLException If the SQL string is invalid for
     *         some reason
     */
    public void execute() {
        acquireReference();
        try {
            getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {
................................................................................
    }

    /**
     * Execute this SQL statement, if the the number of rows affected by execution of this SQL
     * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
     *
     * @return the number of rows affected by this SQL statement execution.
     * @throws android.database.SQLException If the SQL string is invalid for
     *         some reason
     */
    public int executeUpdateDelete() {
        acquireReference();
        try {
            return getSession().executeForChangedRowCount(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
................................................................................

    /**
     * Execute this SQL statement and return the ID of the row inserted due to this call.
     * The SQL statement should be an INSERT for this to be a useful call.
     *
     * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise.
     *
     * @throws android.database.SQLException If the SQL string is invalid for
     *         some reason
     */
    public long executeInsert() {
        acquireReference();
        try {
            return getSession().executeForLastInsertedRowId(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
................................................................................

    /**
     * Execute a statement that returns a 1 by 1 table with a numeric value.
     * For example, SELECT COUNT(*) FROM table;
     *
     * @return The result of the query.
     *
     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
     */
    public long simpleQueryForLong() {
        acquireReference();
        try {
            return getSession().executeForLong(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {
................................................................................

    /**
     * Execute a statement that returns a 1 by 1 table with a text value.
     * For example, SELECT COUNT(*) FROM table;
     *
     * @return The result of the query.
     *
     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
     */
    public String simpleQueryForString() {
        acquireReference();
        try {
            return getSession().executeForString(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {
................................................................................

    /**
     * Executes a statement that returns a 1 by 1 table with a blob value.
     *
     * @return A read-only file descriptor for a copy of the blob value, or {@code null}
     *         if the value is null or could not be read for some reason.
     *
     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
     */
    public ParcelFileDescriptor simpleQueryForBlobFileDescriptor() {
        acquireReference();
        try {
            return getSession().executeForBlobFileDescriptor(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {







|







 







|







 







|







 







|







 







|







 







|







 







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
 * 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 org.sqlite.database.sqlite;

import android.os.ParcelFileDescriptor;

/**
 * Represents a statement that can be executed against a database.  The statement
 * cannot return multiple rows or columns, but single value (1 x 1) result sets
 * are supported.
................................................................................
        super(db, sql, bindArgs, null);
    }

    /**
     * Execute this SQL statement, if it is not a SELECT / INSERT / DELETE / UPDATE, for example
     * CREATE / DROP table, view, trigger, index etc.
     *
     * @throws org.sqlite.database.SQLException If the SQL string is invalid for
     *         some reason
     */
    public void execute() {
        acquireReference();
        try {
            getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {
................................................................................
    }

    /**
     * Execute this SQL statement, if the the number of rows affected by execution of this SQL
     * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
     *
     * @return the number of rows affected by this SQL statement execution.
     * @throws org.sqlite.database.SQLException If the SQL string is invalid for
     *         some reason
     */
    public int executeUpdateDelete() {
        acquireReference();
        try {
            return getSession().executeForChangedRowCount(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
................................................................................

    /**
     * Execute this SQL statement and return the ID of the row inserted due to this call.
     * The SQL statement should be an INSERT for this to be a useful call.
     *
     * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise.
     *
     * @throws org.sqlite.database.SQLException If the SQL string is invalid for
     *         some reason
     */
    public long executeInsert() {
        acquireReference();
        try {
            return getSession().executeForLastInsertedRowId(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
................................................................................

    /**
     * Execute a statement that returns a 1 by 1 table with a numeric value.
     * For example, SELECT COUNT(*) FROM table;
     *
     * @return The result of the query.
     *
     * @throws org.sqlite.database.sqlite.SQLiteDoneException if the query returns zero rows
     */
    public long simpleQueryForLong() {
        acquireReference();
        try {
            return getSession().executeForLong(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {
................................................................................

    /**
     * Execute a statement that returns a 1 by 1 table with a text value.
     * For example, SELECT COUNT(*) FROM table;
     *
     * @return The result of the query.
     *
     * @throws org.sqlite.database.sqlite.SQLiteDoneException if the query returns zero rows
     */
    public String simpleQueryForString() {
        acquireReference();
        try {
            return getSession().executeForString(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {
................................................................................

    /**
     * Executes a statement that returns a 1 by 1 table with a blob value.
     *
     * @return A read-only file descriptor for a copy of the blob value, or {@code null}
     *         if the value is null or could not be read for some reason.
     *
     * @throws org.sqlite.database.sqlite.SQLiteDoneException if the query returns zero rows
     */
    public ParcelFileDescriptor simpleQueryForBlobFileDescriptor() {
        acquireReference();
        try {
            return getSession().executeForBlobFileDescriptor(
                    getSql(), getBindArgs(), getConnectionFlags(), null);
        } catch (SQLiteDatabaseCorruptException ex) {

Changes to src/org/sqlite/database/sqlite/SQLiteStatementInfo.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * Describes a SQLite statement.
 *
 * @hide
 */
public final class SQLiteStatementInfo {







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * Describes a SQLite statement.
 *
 * @hide
 */
public final class SQLiteStatementInfo {

Changes to src/org/sqlite/database/sqlite/SQLiteTableLockedException.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 android.database.sqlite;

public class SQLiteTableLockedException extends SQLiteException {
    public SQLiteTableLockedException() {}

    public SQLiteTableLockedException(String error) {
        super(error);
    }
}







|








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * 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 org.sqlite.database.sqlite;

public class SQLiteTableLockedException extends SQLiteException {
    public SQLiteTableLockedException() {}

    public SQLiteTableLockedException(String error) {
        super(error);
    }
}

Changes to src/org/sqlite/database/sqlite/SQLiteTransactionListener.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 android.database.sqlite;

/**
 * A listener for transaction events.
 */
public interface SQLiteTransactionListener {
    /**
     * Called immediately after the transaction begins.







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * 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 org.sqlite.database.sqlite;

/**
 * A listener for transaction events.
 */
public interface SQLiteTransactionListener {
    /**
     * Called immediately after the transaction begins.

Changes to src/org/sqlite/database/sqlite/SqliteWrapper.java.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * 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 android.database.sqlite;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;

/**
 * @hide
 */
................................................................................
    // FIXME: need to optimize this method.
    private static boolean isLowMemory(SQLiteException e) {
        return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
    }

    public static void checkSQLiteException(Context context, SQLiteException e) {
        if (isLowMemory(e)) {
            Toast.makeText(context, com.android.internal.R.string.low_memory,
                    Toast.LENGTH_SHORT).show();
        } else {
            throw e;
        }
    }

    public static Cursor query(Context context, ContentResolver resolver, Uri uri,
            String[] projection, String selection, String[] selectionArgs, String sortOrder) {







|





|







 







<
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
 * 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 org.sqlite.database.sqlite;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import org.sqlite.database.sqlite.SQLiteException;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;

/**
 * @hide
 */
................................................................................
    // FIXME: need to optimize this method.
    private static boolean isLowMemory(SQLiteException e) {
        return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
    }

    public static void checkSQLiteException(Context context, SQLiteException e) {
        if (isLowMemory(e)) {

            Toast.makeText(context, "low memory", Toast.LENGTH_SHORT).show();
        } else {
            throw e;
        }
    }

    public static Cursor query(Context context, ContentResolver resolver, Uri uri,
            String[] projection, String selection, String[] selectionArgs, String sortOrder) {