diff --git a/C++/sqliteJDBC/sqliteJDBC/NativeDB.c b/C++/sqliteJDBC/sqliteJDBC/NativeDB.c index 9738be406..e5706dc27 100644 --- a/C++/sqliteJDBC/sqliteJDBC/NativeDB.c +++ b/C++/sqliteJDBC/sqliteJDBC/NativeDB.c @@ -20,15 +20,21 @@ #include "NativeDB.h" #include "sqlite3.h" - // Java class variables and method references initialized on library load. - // These classes are weak references to that if the classloader is no longer referenced (garbage) - // It can be garbage collected. The weak references are freed on unload. - // These should not be static variables within methods because assignment in C is not - // guaranteed to be atomic, meaning that one thread may have half initialized a reference - // while another thread reads this half reference resulting in a crash. +// Java class variables and method references initialized on library load. +// These classes are weak references to that if the classloader is no longer referenced (garbage) +// It can be garbage collected. The weak references are freed on unload. +// These should not be static variables within methods because assignment in C is not +// guaranteed to be atomic, meaning that one thread may have half initialized a reference +// while another thread reads this half reference resulting in a crash. static jclass dbclass = 0; static jfieldID dbpointer = 0; +static jfieldID db_busyHandler = 0; +static jfieldID db_commitListener = 0; +static jfieldID db_updateListener = 0; +static jfieldID db_progressHandler = 0; +static jmethodID db_mth_onUpdate = 0; +static jmethodID db_mth_onCommit = 0; static jmethodID mth_stringToUtf8ByteArray = 0; static jmethodID mth_throwex = 0; static jmethodID mth_throwexcode = 0; @@ -36,8 +42,8 @@ static jmethodID mth_throwexmsg = 0; static jclass fclass = 0; static jfieldID func_context = 0, -func_value = 0, -func_args = 0; + func_value = 0, + func_args = 0; static jmethodID fmethod = 0; static jclass cclass = 0; @@ -52,1428 +58,1481 @@ static jclass wclass = 0; static jmethodID w_mth_inverse = 0; static jmethodID w_mth_xvalue = 0; -static jclass pclass = 0; +static jclass pobserverclass = 0; +static jmethodID pobserver_mth_progress = 0; + static jclass phandleclass = 0; -static jmethodID pmethod = 0; +static jmethodID phandle_mth_progress = 0; + +static jclass bhandleclass = 0; +static jmethodID bhandle_mth_callback = 0; +static jclass exclass = 0; static jmethodID exp_msg = 0; -static void* toref(jlong value) +static jclass bool_array_class = 0; + +static void * toref(jlong value) { - void* ret; - memcpy(&ret, &value, sizeof(void*)); - return ret; + void * ret; + memcpy(&ret, &value, sizeof(void*)); + return ret; } -static jlong fromref(void* value) +static jlong fromref(void * value) { - jlong ret; - memcpy(&ret, &value, sizeof(void*)); - return ret; + jlong ret; + memcpy(&ret, &value, sizeof(void*)); + return ret; } -static void throwex(JNIEnv* env, jobject this) +static void throwex(JNIEnv *env, jobject this) { - (*env)->CallVoidMethod(env, this, mth_throwex); + (*env)->CallVoidMethod(env, this, mth_throwex); } -static void throwex_errorcode(JNIEnv* env, jobject this, int errorCode) +static void throwex_errorcode(JNIEnv *env, jobject this, int errorCode) { - (*env)->CallVoidMethod(env, this, mth_throwexcode, (jint)errorCode); + (*env)->CallVoidMethod(env, this, mth_throwexcode, (jint) errorCode); } -static void throwex_msg(JNIEnv* env, const char* str) +static void throwex_msg(JNIEnv *env, const char *str) { - (*env)->CallStaticVoidMethod(env, dbclass, mth_throwexmsg, - (*env)->NewStringUTF(env, str)); + (*env)->CallStaticVoidMethod(env, dbclass, mth_throwexmsg, + (*env)->NewStringUTF(env, str)); } -static void throwex_outofmemory(JNIEnv* env) +static void throwex_outofmemory(JNIEnv *env) { - throwex_msg(env, "Out of memory"); + throwex_msg(env, "Out of memory"); } -static void throwex_stmt_finalized(JNIEnv* env) +static void throwex_stmt_finalized(JNIEnv *env) { - throwex_msg(env, "The prepared statement has been finalized"); + throwex_msg(env, "The prepared statement has been finalized"); } -static void throwex_db_closed(JNIEnv* env) +static void throwex_db_closed(JNIEnv *env) { - throwex_msg(env, "The database has been closed"); + throwex_msg(env, "The database has been closed"); } -static jobject utf8BytesToDirectByteBuffer(JNIEnv* env, const char* bytes, int nbytes) +static jobject utf8BytesToDirectByteBuffer(JNIEnv *env, const char* bytes, int nbytes) { - jobject result; + jobject result; - if (!bytes) - { - return NULL; - } + if (!bytes) + { + return NULL; + } - result = (*env)->NewDirectByteBuffer(env, (void*)bytes, nbytes); - if (!result) - { - throwex_outofmemory(env); - return NULL; - } + result = (*env)->NewDirectByteBuffer(env, (void*) bytes, nbytes); + if (!result) + { + throwex_outofmemory(env); + return NULL; + } - return result; + return result; } -static void utf8JavaByteArrayToUtf8Bytes(JNIEnv* env, jbyteArray utf8bytes, char** bytes, int* nbytes) +static void utf8JavaByteArrayToUtf8Bytes(JNIEnv *env, jbyteArray utf8bytes, char** bytes, int* nbytes) { - jsize utf8bytes_length; - char* buf; + jsize utf8bytes_length; + char* buf; - *bytes = NULL; - if (nbytes) *nbytes = 0; + *bytes = NULL; + if (nbytes) *nbytes = 0; - if (!utf8bytes) - { - return; - } + if (!utf8bytes) + { + return; + } - utf8bytes_length = (*env)->GetArrayLength(env, (jarray)utf8bytes); + utf8bytes_length = (*env)->GetArrayLength(env, (jarray) utf8bytes); - buf = (char*)malloc(utf8bytes_length + 1); - if (!buf) - { - throwex_outofmemory(env); - return; - } + buf = (char*) malloc(utf8bytes_length + 1); + if (!buf) + { + throwex_outofmemory(env); + return; + } - (*env)->GetByteArrayRegion(env, utf8bytes, 0, utf8bytes_length, (jbyte*)buf); + (*env)->GetByteArrayRegion(env, utf8bytes, 0, utf8bytes_length, (jbyte*)buf); - buf[utf8bytes_length] = '\0'; + buf[utf8bytes_length] = '\0'; - *bytes = buf; - if (nbytes) *nbytes = (int)utf8bytes_length; + *bytes = buf; + if (nbytes) *nbytes = (int) utf8bytes_length; } -static jbyteArray stringToUtf8ByteArray(JNIEnv* env, jstring str) +static jbyteArray stringToUtf8ByteArray(JNIEnv *env, jstring str) { - jobject result; + jobject result; - result = (*env)->CallStaticObjectMethod(env, dbclass, mth_stringToUtf8ByteArray, str); + result = (*env)->CallStaticObjectMethod(env, dbclass, mth_stringToUtf8ByteArray, str); - return (jbyteArray)result; + return (jbyteArray) result; } -static void stringToUtf8Bytes(JNIEnv* env, jstring str, char** bytes, int* nbytes) +static void stringToUtf8Bytes(JNIEnv *env, jstring str, char** bytes, int* nbytes) { - jbyteArray utf8bytes; - jsize utf8bytes_length; - char* buf; + jbyteArray utf8bytes; + jsize utf8bytes_length; + char* buf; - *bytes = NULL; - if (nbytes) *nbytes = 0; + *bytes = NULL; + if (nbytes) *nbytes = 0; - if (!str) - { - return; - } + if (!str) + { + return; + } - utf8bytes = stringToUtf8ByteArray(env, str); - if (!utf8bytes) - { - return; - } + utf8bytes = stringToUtf8ByteArray(env, str); + if (!utf8bytes) + { + return; + } - utf8bytes_length = (*env)->GetArrayLength(env, (jarray)utf8bytes); + utf8bytes_length = (*env)->GetArrayLength(env, (jarray) utf8bytes); - buf = (char*)malloc(utf8bytes_length + 1); - if (!buf) - { - throwex_outofmemory(env); - return; - } + buf = (char*) malloc(utf8bytes_length + 1); + if (!buf) + { + throwex_outofmemory(env); + return; + } - (*env)->GetByteArrayRegion(env, utf8bytes, 0, utf8bytes_length, (jbyte*)buf); + (*env)->GetByteArrayRegion(env, utf8bytes, 0, utf8bytes_length, (jbyte*)buf); - buf[utf8bytes_length] = '\0'; + buf[utf8bytes_length] = '\0'; - *bytes = buf; - if (nbytes) *nbytes = (int)utf8bytes_length; + *bytes = buf; + if (nbytes) *nbytes = (int) utf8bytes_length; } static void freeUtf8Bytes(char* bytes) { - if (bytes) - { - free(bytes); - } + if (bytes) + { + free(bytes); + } } -static sqlite3* gethandle(JNIEnv* env, jobject nativeDB) +static sqlite3 * gethandle(JNIEnv *env, jobject nativeDB) { - return (sqlite3*)toref((*env)->GetLongField(env, nativeDB, dbpointer)); + return (sqlite3 *)toref((*env)->GetLongField(env, nativeDB, dbpointer)); } -static void sethandle(JNIEnv* env, jobject nativeDB, sqlite3* ref) +static void sethandle(JNIEnv *env, jobject nativeDB, sqlite3 * ref) { - (*env)->SetLongField(env, nativeDB, dbpointer, fromref(ref)); + (*env)->SetLongField(env, nativeDB, dbpointer, fromref(ref)); } struct BusyHandlerContext { - JavaVM* vm; - jmethodID methodId; - jobject obj; + JavaVM * vm; + jobject obj; }; -static void free_busy_handler(JNIEnv* env, void* toFree) { - struct BusyHandlerContext* busyHandlerContext = (struct BusyHandlerContext*)toFree; - (*env)->DeleteGlobalRef(env, busyHandlerContext->obj); - free(toFree); +static void free_busy_handler(JNIEnv *env, void *toFree) { + struct BusyHandlerContext* busyHandlerContext = (struct BusyHandlerContext*) toFree; + (*env)->DeleteGlobalRef(env, busyHandlerContext->obj); + free(toFree); } -static void set_new_handler(JNIEnv* env, jobject nativeDB, char* fieldName, - void* newHandler, void (*free_handler)(JNIEnv*, void*)) +static void set_new_handler(JNIEnv *env, jobject nativeDB, jfieldID handlerField, + void * newHandler, void (*free_handler)(JNIEnv*, void*)) { - jfieldID handlerField = (*env)->GetFieldID(env, dbclass, fieldName, "J"); - assert(handlerField); - - void* toFree = toref((*env)->GetLongField(env, nativeDB, handlerField)); - if (toFree) { - free_handler(env, toFree); - } + void *toFree = toref((*env)->GetLongField(env, nativeDB, handlerField)); + if (toFree) { + free_handler(env, toFree); + } - (*env)->SetLongField(env, nativeDB, handlerField, fromref(newHandler)); + (*env)->SetLongField(env, nativeDB, handlerField, fromref(newHandler)); } struct CollationData { - JavaVM* vm; - jobject func; + JavaVM *vm; + jobject func; }; // User Defined Function SUPPORT //////////////////////////////////// struct UDFData { - JavaVM* vm; - jobject func; + JavaVM *vm; + jobject func; }; /* Returns the sqlite3_value for the given arg of the given function. * If 0 is returned, an exception has been thrown to report the reason. */ -static sqlite3_value* tovalue(JNIEnv* env, jobject function, jint arg) +static sqlite3_value * tovalue(JNIEnv *env, jobject function, jint arg) { - jlong value_pntr = 0; - jint numArgs = 0; + jlong value_pntr = 0; + jint numArgs = 0; - // check we have any business being here - if (arg < 0) { throwex_msg(env, "negative arg out of range"); return 0; } - if (!function) { throwex_msg(env, "inconstent function"); return 0; } + // check we have any business being here + if (arg < 0) { throwex_msg(env, "negative arg out of range"); return 0; } + if (!function) { throwex_msg(env, "inconsistent function"); return 0; } - value_pntr = (*env)->GetLongField(env, function, func_value); - numArgs = (*env)->GetIntField(env, function, func_args); + value_pntr = (*env)->GetLongField(env, function, func_value); + numArgs = (*env)->GetIntField(env, function, func_args); - if (value_pntr == 0) { throwex_msg(env, "no current value"); return 0; } - if (arg >= numArgs) { throwex_msg(env, "arg out of range"); return 0; } + if (value_pntr == 0) { throwex_msg(env, "no current value"); return 0; } + if (arg >= numArgs) { throwex_msg(env, "arg out of range"); return 0; } - return ((sqlite3_value**)toref(value_pntr))[arg]; + return ((sqlite3_value**)toref(value_pntr))[arg]; } -/* called if an exception occured processing xFunc */ -static void xFunc_error(sqlite3_context* context, JNIEnv* env) +/* called if an exception occurred processing xFunc */ +static void xFunc_error(sqlite3_context *context, JNIEnv *env) { - jstring msg = 0; - char* msg_bytes; - int msg_nbytes; + jstring msg = 0; + char *msg_bytes; + int msg_nbytes; - jthrowable ex = (*env)->ExceptionOccurred(env); + jthrowable ex = (*env)->ExceptionOccurred(env); - (*env)->ExceptionClear(env); + (*env)->ExceptionClear(env); - msg = (jstring)(*env)->CallObjectMethod(env, ex, exp_msg); - if (!msg) { sqlite3_result_error(context, "unknown error", 13); return; } + msg = (jstring)(*env)->CallObjectMethod(env, ex, exp_msg); + if (!msg) { sqlite3_result_error(context, "unknown error", 13); return; } - stringToUtf8Bytes(env, msg, &msg_bytes, &msg_nbytes); - if (!msg_bytes) { sqlite3_result_error_nomem(context); return; } + stringToUtf8Bytes(env, msg, &msg_bytes, &msg_nbytes); + if (!msg_bytes) { sqlite3_result_error_nomem(context); return; } - sqlite3_result_error(context, msg_bytes, msg_nbytes); - freeUtf8Bytes(msg_bytes); + sqlite3_result_error(context, msg_bytes, msg_nbytes); + freeUtf8Bytes(msg_bytes); } /* used to call xFunc, xStep and xFinal */ static void xCall( - sqlite3_context* context, - int args, - sqlite3_value** value, - jobject func, - jmethodID method) + sqlite3_context *context, + int args, + sqlite3_value** value, + jobject func, + jmethodID method) { - JNIEnv* env = 0; - struct UDFData* udf = 0; + JNIEnv *env = 0; + struct UDFData *udf = 0; - udf = (struct UDFData*)sqlite3_user_data(context); - assert(udf); - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); - if (!func) func = udf->func; + udf = (struct UDFData*)sqlite3_user_data(context); + assert(udf); + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); + if (!func) func = udf->func; - (*env)->SetLongField(env, func, func_context, fromref(context)); - (*env)->SetLongField(env, func, func_value, value ? fromref(value) : 0); - (*env)->SetIntField(env, func, func_args, args); + (*env)->SetLongField(env, func, func_context, fromref(context)); + (*env)->SetLongField(env, func, func_value, value ? fromref(value) : 0); + (*env)->SetIntField(env, func, func_args, args); - (*env)->CallVoidMethod(env, func, method); + (*env)->CallVoidMethod(env, func, method); - // check if xFunc threw an Exception - if ((*env)->ExceptionCheck(env)) { - xFunc_error(context, env); - } + // check if xFunc threw an Exception + if ((*env)->ExceptionCheck(env)) { + xFunc_error(context, env); + } - (*env)->SetLongField(env, func, func_context, 0); - (*env)->SetLongField(env, func, func_value, 0); - (*env)->SetIntField(env, func, func_args, 0); + (*env)->SetLongField(env, func, func_context, 0); + (*env)->SetLongField(env, func, func_value, 0); + (*env)->SetIntField(env, func, func_args, 0); } -void xFunc(sqlite3_context* context, int args, sqlite3_value** value) +void xFunc(sqlite3_context *context, int args, sqlite3_value** value) { - JNIEnv* env; - struct UDFData* udf = (struct UDFData*)sqlite3_user_data(context); - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); - xCall(context, args, value, 0, fmethod); + JNIEnv *env; + struct UDFData *udf = (struct UDFData*)sqlite3_user_data(context); + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); + xCall(context, args, value, 0, fmethod); } -static jobject* get_initialized_udf_context(sqlite3_context* context) { - // clone the Function.Aggregate instance and store a pointer - // in SQLite's aggregate_context (clean up in xFinal) - jobject* func = sqlite3_aggregate_context(context, sizeof(jobject)); - if (!*func) { - JNIEnv* env; - struct UDFData* udf = (struct UDFData*)sqlite3_user_data(context); - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); +static jobject* get_initialized_udf_context(sqlite3_context *context) { + // clone the Function.Aggregate instance and store a pointer + // in SQLite's aggregate_context (clean up in xFinal) + jobject *func = sqlite3_aggregate_context(context, sizeof(jobject)); + if (!*func) { + JNIEnv *env; + struct UDFData *udf = (struct UDFData*)sqlite3_user_data(context); + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); - *func = (*env)->CallObjectMethod(env, udf->func, aclone); - *func = (*env)->NewGlobalRef(env, *func); - } - return func; + *func = (*env)->CallObjectMethod(env, udf->func, aclone); + *func = (*env)->NewGlobalRef(env, *func); + } + return func; } -void xStep(sqlite3_context* context, int args, sqlite3_value** value) +void xStep(sqlite3_context *context, int args, sqlite3_value** value) { - // clone the Function.Aggregate instance and store a pointer - // in SQLite's aggregate_context (clean up in xFinal) - jobject* func = get_initialized_udf_context(context); - xCall(context, args, value, *func, mth_aggr_xstep); + // clone the Function.Aggregate instance and store a pointer + // in SQLite's aggregate_context (clean up in xFinal) + jobject *func = get_initialized_udf_context(context); + xCall(context, args, value, *func, mth_aggr_xstep); } -void xInverse(sqlite3_context* context, int args, sqlite3_value** value) +void xInverse(sqlite3_context *context, int args, sqlite3_value** value) { - JNIEnv* env = 0; - struct UDFData* udf = 0; - jobject* func = 0; + JNIEnv *env = 0; + struct UDFData *udf = 0; + jobject *func = 0; - udf = (struct UDFData*)sqlite3_user_data(context); - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); + udf = (struct UDFData*)sqlite3_user_data(context); + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); - func = sqlite3_aggregate_context(context, sizeof(jobject)); - assert(*func); // disaster + func = sqlite3_aggregate_context(context, sizeof(jobject)); + assert(*func); // disaster - xCall(context, args, value, *func, w_mth_inverse); + xCall(context, args, value, *func, w_mth_inverse); } -void xValue(sqlite3_context* context) +void xValue(sqlite3_context *context) { - JNIEnv* env = 0; - struct UDFData* udf = 0; - jobject* func = 0; + JNIEnv *env = 0; + struct UDFData *udf = 0; + jobject *func = 0; - udf = (struct UDFData*)sqlite3_user_data(context); - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); + udf = (struct UDFData*)sqlite3_user_data(context); + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); - func = sqlite3_aggregate_context(context, sizeof(jobject)); - assert(*func); // disaster + func = sqlite3_aggregate_context(context, sizeof(jobject)); + assert(*func); // disaster - xCall(context, 0, 0, *func, w_mth_xvalue); + xCall(context, 0, 0, *func, w_mth_xvalue); } -void xFinal(sqlite3_context* context) +void xFinal(sqlite3_context *context) { - JNIEnv* env = 0; + JNIEnv *env = 0; - struct UDFData* udf = (struct UDFData*)sqlite3_user_data(context); + struct UDFData *udf = (struct UDFData*)sqlite3_user_data(context); - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); - // func may not have been allocated if xStep never ran - jobject* func = get_initialized_udf_context(context); - xCall(context, 0, 0, *func, mth_aggr_xfinal); + // func may not have been allocated if xStep never ran + jobject *func = get_initialized_udf_context(context); + xCall(context, 0, 0, *func, mth_aggr_xfinal); - // clean up Function.Aggregate instance - (*env)->DeleteGlobalRef(env, *func); + // clean up Function.Aggregate instance + (*env)->DeleteGlobalRef(env, *func); } int xCompare(void* context, int len1, const void* str1, int len2, const void* str2) { - JNIEnv* env; - struct CollationData* coll = (struct CollationData*)context; - (*coll->vm)->AttachCurrentThread(coll->vm, (void**)&env, 0); + JNIEnv *env; + struct CollationData *coll = (struct CollationData*)context; + (*coll->vm)->AttachCurrentThread(coll->vm, (void **)&env, 0); - // According to https://bugs.openjdk.java.net/browse/JDK-8163861 the len param of NewString - // expects a length in terms of code unit. Being UTF-16, code unit is 16 bits - // SQLite pass the length in bytes for len1 and len2, which is 8 bits - jstring jstr1 = (*env)->NewString(env, str1, len1 / 2); - jstring jstr2 = (*env)->NewString(env, str2, len2 / 2); + // According to https://bugs.openjdk.java.net/browse/JDK-8163861 the len param of NewString + // expects a length in terms of code unit. Being UTF-16, code unit is 16 bits + // SQLite pass the length in bytes for len1 and len2, which is 8 bits + jstring jstr1 = (*env)->NewString(env, str1, len1 / 2); + jstring jstr2 = (*env)->NewString(env, str2, len2 / 2); - return (*env)->CallIntMethod(env, coll->func, mth_compare, jstr1, jstr2); + return (*env)->CallIntMethod(env, coll->func, mth_compare, jstr1, jstr2); } // INITIALISATION /////////////////////////////////////////////////// -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) -{ - JNIEnv* env = 0; - - if (JNI_OK != (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_2)) - return JNI_ERR; - - dbclass = (*env)->FindClass(env, "org/sqlite/core/NativeDB"); - if (!dbclass) return JNI_ERR; - dbclass = (*env)->NewWeakGlobalRef(env, dbclass); - dbpointer = (*env)->GetFieldID(env, dbclass, "pointer", "J"); - mth_stringToUtf8ByteArray = (*env)->GetStaticMethodID( - env, dbclass, "stringToUtf8ByteArray", "(Ljava/lang/String;)[B"); - mth_throwex = (*env)->GetMethodID(env, dbclass, "throwex", "()V"); - mth_throwexcode = (*env)->GetMethodID(env, dbclass, "throwex", "(I)V"); - mth_throwexmsg = (*env)->GetStaticMethodID(env, dbclass, "throwex", "(Ljava/lang/String;)V"); - - fclass = (*env)->FindClass(env, "org/sqlite/Function"); - if (!fclass) return JNI_ERR; - fclass = (*env)->NewWeakGlobalRef(env, fclass); - func_context = (*env)->GetFieldID(env, fclass, "context", "J"); - func_value = (*env)->GetFieldID(env, fclass, "value", "J"); - func_args = (*env)->GetFieldID(env, fclass, "args", "I"); - fmethod = (*env)->GetMethodID(env, fclass, "xFunc", "()V"); - - cclass = (*env)->FindClass(env, "org/sqlite/Collation"); - if (!cclass) return JNI_ERR; - cclass = (*env)->NewWeakGlobalRef(env, cclass); - mth_compare = (*env)->GetMethodID(env, cclass, "xCompare", "(Ljava/lang/String;Ljava/lang/String;)I"); - - aclass = (*env)->FindClass(env, "org/sqlite/Function$Aggregate"); - if (!aclass) return JNI_ERR; - aclass = (*env)->NewWeakGlobalRef(env, aclass); - mth_aggr_xstep = (*env)->GetMethodID(env, aclass, "xStep", "()V"); - mth_aggr_xfinal = (*env)->GetMethodID(env, aclass, "xFinal", "()V"); - aclone = (*env)->GetMethodID(env, aclass, "clone", "()Ljava/lang/Object;"); - - wclass = (*env)->FindClass(env, "org/sqlite/Function$Window"); - if (!wclass) return JNI_ERR; - wclass = (*env)->NewWeakGlobalRef(env, wclass); - w_mth_inverse = (*env)->GetMethodID(env, wclass, "xInverse", "()V"); - w_mth_xvalue = (*env)->GetMethodID(env, wclass, "xValue", "()V"); - - pclass = (*env)->FindClass(env, "org/sqlite/core/DB$ProgressObserver"); - if (!pclass) return JNI_ERR; - pclass = (*env)->NewWeakGlobalRef(env, pclass); - pmethod = (*env)->GetMethodID(env, pclass, "progress", "(II)V"); - - phandleclass = (*env)->FindClass(env, "org/sqlite/ProgressHandler"); - if (!phandleclass) return JNI_ERR; - phandleclass = (*env)->NewWeakGlobalRef(env, phandleclass); - - jclass exclass = (*env)->FindClass(env, "java/lang/Throwable"); - exp_msg = (*env)->GetMethodID( - env, exclass, "toString", "()Ljava/lang/String;"); - - return JNI_VERSION_1_2; +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) +{ + JNIEnv* env = 0; + + if (JNI_OK != (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2)) + return JNI_ERR; + + dbclass = (*env)->FindClass(env, "org/sqlite/core/NativeDB"); + if (!dbclass) return JNI_ERR; + dbclass = (*env)->NewWeakGlobalRef(env, dbclass); + dbpointer = (*env)->GetFieldID(env, dbclass, "pointer", "J"); + db_busyHandler = (*env)->GetFieldID(env, dbclass, "busyHandler", "J"); + db_commitListener = (*env)->GetFieldID(env, dbclass, "commitListener", "J"); + db_updateListener = (*env)->GetFieldID(env, dbclass, "updateListener", "J"); + db_progressHandler = (*env)->GetFieldID(env, dbclass, "progressHandler", "J"); + db_mth_onUpdate = (*env)->GetMethodID(env, dbclass, "onUpdate", "(ILjava/lang/String;Ljava/lang/String;J)V"); + db_mth_onCommit = (*env)->GetMethodID(env, dbclass, "onCommit", "(Z)V"); + mth_stringToUtf8ByteArray = (*env)->GetStaticMethodID( + env, dbclass, "stringToUtf8ByteArray", "(Ljava/lang/String;)[B"); + mth_throwex = (*env)->GetMethodID(env, dbclass, "throwex", "()V"); + mth_throwexcode = (*env)->GetMethodID(env, dbclass, "throwex", "(I)V"); + mth_throwexmsg = (*env)->GetStaticMethodID(env, dbclass, "throwex", "(Ljava/lang/String;)V"); + + fclass = (*env)->FindClass(env, "org/sqlite/Function"); + if (!fclass) return JNI_ERR; + fclass = (*env)->NewWeakGlobalRef(env, fclass); + func_context = (*env)->GetFieldID(env, fclass, "context", "J"); + func_value = (*env)->GetFieldID(env, fclass, "value", "J"); + func_args = (*env)->GetFieldID(env, fclass, "args", "I"); + fmethod = (*env)->GetMethodID(env, fclass, "xFunc", "()V"); + + cclass = (*env)->FindClass(env, "org/sqlite/Collation"); + if (!cclass) return JNI_ERR; + cclass = (*env)->NewWeakGlobalRef(env, cclass); + mth_compare = (*env)->GetMethodID(env, cclass, "xCompare", "(Ljava/lang/String;Ljava/lang/String;)I"); + + aclass = (*env)->FindClass(env, "org/sqlite/Function$Aggregate"); + if (!aclass) return JNI_ERR; + aclass = (*env)->NewWeakGlobalRef(env, aclass); + mth_aggr_xstep = (*env)->GetMethodID(env, aclass, "xStep", "()V"); + mth_aggr_xfinal = (*env)->GetMethodID(env, aclass, "xFinal", "()V"); + aclone = (*env)->GetMethodID(env, aclass, "clone", "()Ljava/lang/Object;"); + + wclass = (*env)->FindClass(env, "org/sqlite/Function$Window"); + if (!wclass) return JNI_ERR; + wclass = (*env)->NewWeakGlobalRef(env, wclass); + w_mth_inverse = (*env)->GetMethodID(env, wclass, "xInverse", "()V"); + w_mth_xvalue = (*env)->GetMethodID(env, wclass, "xValue", "()V"); + + pobserverclass = (*env)->FindClass(env, "org/sqlite/core/DB$ProgressObserver"); + if(!pobserverclass) return JNI_ERR; + pobserverclass = (*env)->NewWeakGlobalRef(env, pobserverclass); + pobserver_mth_progress = (*env)->GetMethodID(env, pobserverclass, "progress", "(II)V"); + + phandleclass = (*env)->FindClass(env, "org/sqlite/ProgressHandler"); + if(!phandleclass) return JNI_ERR; + phandleclass = (*env)->NewWeakGlobalRef(env, phandleclass); + phandle_mth_progress = (*env)->GetMethodID(env, phandleclass, "progress", "()I"); + + bhandleclass = (*env)->FindClass(env, "org/sqlite/BusyHandler"); + if(!bhandleclass) return JNI_ERR; + bhandleclass = (*env)->NewWeakGlobalRef(env, bhandleclass); + bhandle_mth_callback = (*env)->GetMethodID(env, bhandleclass, "callback", "(I)I"); + + exclass = (*env)->FindClass(env, "java/lang/Throwable"); + if(!exclass) return JNI_ERR; + exclass = (*env)->NewWeakGlobalRef(env, exclass); + exp_msg = (*env)->GetMethodID( + env, exclass, "toString", "()Ljava/lang/String;"); + + bool_array_class = (*env)->FindClass(env, "[Z"); + if(!bool_array_class) return JNI_ERR; + bool_array_class = (*env)->NewWeakGlobalRef(env, bool_array_class); + + return JNI_VERSION_1_2; } // FINALIZATION -JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) { - JNIEnv* env = 0; +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { + JNIEnv* env = 0; + + if (JNI_OK != (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2)) + return; + + if (dbclass) (*env)->DeleteWeakGlobalRef(env, dbclass); + + if (fclass) (*env)->DeleteWeakGlobalRef(env, fclass); - if (JNI_OK != (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_2)) - return; + if (cclass) (*env)->DeleteWeakGlobalRef(env, cclass); - if (dbclass) (*env)->DeleteWeakGlobalRef(env, dbclass); + if (aclass) (*env)->DeleteWeakGlobalRef(env, aclass); - if (fclass) (*env)->DeleteWeakGlobalRef(env, fclass); + if (wclass) (*env)->DeleteWeakGlobalRef(env, wclass); - if (cclass) (*env)->DeleteWeakGlobalRef(env, cclass); + if (pobserverclass) (*env)->DeleteWeakGlobalRef(env, pobserverclass); - if (aclass) (*env)->DeleteWeakGlobalRef(env, aclass); + if (phandleclass) (*env)->DeleteWeakGlobalRef(env, phandleclass); - if (wclass) (*env)->DeleteWeakGlobalRef(env, wclass); + if (bhandleclass) (*env)->DeleteWeakGlobalRef(env, bhandleclass); - if (pclass) (*env)->DeleteWeakGlobalRef(env, pclass); + if (exclass) (*env)->DeleteWeakGlobalRef(env, exclass); - if (phandleclass) (*env)->DeleteWeakGlobalRef(env, phandleclass); + if (bool_array_class) (*env)->DeleteWeakGlobalRef(env, bool_array_class); } // WRAPPERS for sqlite_* functions ////////////////////////////////// JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_shared_1cache( - JNIEnv* env, jobject this, jboolean enable) + JNIEnv *env, jobject this, jboolean enable) { - return sqlite3_enable_shared_cache(enable ? 1 : 0); + return sqlite3_enable_shared_cache(enable ? 1 : 0); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_enable_1load_1extension( - JNIEnv* env, jobject this, jboolean enable) + JNIEnv *env, jobject this, jboolean enable) { - sqlite3* db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return SQLITE_MISUSE; - } + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return SQLITE_MISUSE; + } - return sqlite3_enable_load_extension(db, enable ? 1 : 0); + return sqlite3_enable_load_extension(db, enable ? 1 : 0); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB__1open_1utf8( - JNIEnv* env, jobject this, jbyteArray file, jint flags) + JNIEnv *env, jobject this, jbyteArray file, jint flags) { - sqlite3* db; - int ret; - char* file_bytes; + sqlite3 *db; + int ret; + char *file_bytes; - db = gethandle(env, this); - if (db) { - throwex_msg(env, "DB already open"); - sqlite3_close(db); - return; - } + db = gethandle(env, this); + if (db) { + throwex_msg(env, "DB already open"); + sqlite3_close(db); + return; + } - utf8JavaByteArrayToUtf8Bytes(env, file, &file_bytes, NULL); - if (!file_bytes) return; + utf8JavaByteArrayToUtf8Bytes(env, file, &file_bytes, NULL); + if (!file_bytes) return; - ret = sqlite3_open_v2(file_bytes, &db, flags, NULL); - freeUtf8Bytes(file_bytes); + ret = sqlite3_open_v2(file_bytes, &db, flags, NULL); + freeUtf8Bytes(file_bytes); - sethandle(env, this, db); - if (ret != SQLITE_OK) { - ret = sqlite3_extended_errcode(db); - throwex_errorcode(env, this, ret); - sethandle(env, this, 0); // The handle is needed for throwex_errorcode - sqlite3_close(db); - return; - } + sethandle(env, this, db); + if (ret != SQLITE_OK) { + ret = sqlite3_extended_errcode(db); + throwex_errorcode(env, this, ret); + sethandle(env, this, 0); // The handle is needed for throwex_errorcode + sqlite3_close(db); + return; + } - // Ignore failures, as we can tolerate regular result codes. - (void)sqlite3_extended_result_codes(db, 1); + // Ignore failures, as we can tolerate regular result codes. + (void) sqlite3_extended_result_codes(db, 1); } -JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_interrupt(JNIEnv* env, jobject this) +JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_interrupt(JNIEnv *env, jobject this) { - sqlite3* db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return; - } + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return; + } - sqlite3_interrupt(db); + sqlite3_interrupt(db); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_busy_1timeout( - JNIEnv* env, jobject this, jint ms) + JNIEnv *env, jobject this, jint ms) { - sqlite3* db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return; - } + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return; + } - sqlite3_busy_timeout(db, ms); + sqlite3_busy_timeout(db, ms); } int busyHandlerCallBack(void* callback, int nbPrevInvok) { - JNIEnv* env = 0; + JNIEnv *env = 0; - struct BusyHandlerContext* busyHandlerContext = (struct BusyHandlerContext*)callback; - (*(busyHandlerContext->vm))->AttachCurrentThread(busyHandlerContext->vm, (void**)&env, 0); + struct BusyHandlerContext *busyHandlerContext = (struct BusyHandlerContext*) callback; + (*(busyHandlerContext->vm))->AttachCurrentThread(busyHandlerContext->vm, (void **)&env, 0); - return (*env)->CallIntMethod(env, - busyHandlerContext->obj, - busyHandlerContext->methodId, - nbPrevInvok); + return (*env)->CallIntMethod(env, + busyHandlerContext->obj, + bhandle_mth_callback, + nbPrevInvok); } -void change_busy_handler(JNIEnv* env, jobject nativeDB, jobject busyHandler) +void change_busy_handler(JNIEnv *env, jobject nativeDB, jobject busyHandler) { - sqlite3* db; + sqlite3 *db; - db = gethandle(env, nativeDB); - if (!db) { - throwex_db_closed(env); - return; - } + db = gethandle(env, nativeDB); + if (!db){ + throwex_db_closed(env); + return; + } - struct BusyHandlerContext* busyHandlerContext = NULL; + struct BusyHandlerContext* busyHandlerContext = NULL; - if (busyHandler) { - busyHandlerContext = (struct BusyHandlerContext*)malloc(sizeof(struct BusyHandlerContext)); - (*env)->GetJavaVM(env, &busyHandlerContext->vm); + if (busyHandler) { + busyHandlerContext = (struct BusyHandlerContext*) malloc(sizeof(struct BusyHandlerContext)); + (*env)->GetJavaVM(env, &busyHandlerContext->vm); - busyHandlerContext->obj = (*env)->NewGlobalRef(env, busyHandler); - busyHandlerContext->methodId = (*env)->GetMethodID(env, - (*env)->GetObjectClass(env, busyHandlerContext->obj), - "callback", - "(I)I"); - } + busyHandlerContext->obj = (*env)->NewGlobalRef(env, busyHandler); + } - if (busyHandlerContext) { - sqlite3_busy_handler(db, &busyHandlerCallBack, busyHandlerContext); - } - else { - sqlite3_busy_handler(db, NULL, NULL); - } + if (busyHandlerContext) { + sqlite3_busy_handler(db, &busyHandlerCallBack, busyHandlerContext); + } else { + sqlite3_busy_handler(db, NULL, NULL); + } - set_new_handler(env, nativeDB, "busyHandler", busyHandlerContext, &free_busy_handler); + set_new_handler(env, nativeDB, db_busyHandler, busyHandlerContext, &free_busy_handler); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_busy_1handler( - JNIEnv* env, jobject nativeDB, jobject busyHandler) { - change_busy_handler(env, nativeDB, busyHandler); + JNIEnv *env, jobject nativeDB, jobject busyHandler) { + change_busy_handler(env, nativeDB, busyHandler); } JNIEXPORT jlong JNICALL Java_org_sqlite_core_NativeDB_prepare_1utf8( - JNIEnv* env, jobject this, jbyteArray sql) + JNIEnv *env, jobject this, jbyteArray sql) { - sqlite3* db; - sqlite3_stmt* stmt; - char* sql_bytes; - int sql_nbytes; - int status; + sqlite3* db; + sqlite3_stmt* stmt; + char* sql_bytes; + int sql_nbytes; + int status; - db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return 0; - } + db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return 0; + } - utf8JavaByteArrayToUtf8Bytes(env, sql, &sql_bytes, &sql_nbytes); - if (!sql_bytes) return fromref(0); + utf8JavaByteArrayToUtf8Bytes(env, sql, &sql_bytes, &sql_nbytes); + if (!sql_bytes) return fromref(0); - status = sqlite3_prepare_v2(db, sql_bytes, sql_nbytes, &stmt, 0); - freeUtf8Bytes(sql_bytes); + status = sqlite3_prepare_v2(db, sql_bytes, sql_nbytes, &stmt, 0); + freeUtf8Bytes(sql_bytes); - if (status != SQLITE_OK) { - throwex_errorcode(env, this, status); - return fromref(0); - } - return fromref(stmt); + if (status != SQLITE_OK) { + throwex_errorcode(env, this, status); + return fromref(0); + } + return fromref(stmt); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB__1exec_1utf8( - JNIEnv* env, jobject this, jbyteArray sql) + JNIEnv *env, jobject this, jbyteArray sql) { - sqlite3* db; - char* sql_bytes; - int status; + sqlite3* db; + char* sql_bytes; + int status; - db = gethandle(env, this); - if (!db) - { - throwex_errorcode(env, this, SQLITE_MISUSE); - return SQLITE_MISUSE; - } + db = gethandle(env, this); + if (!db) + { + throwex_errorcode(env, this, SQLITE_MISUSE); + return SQLITE_MISUSE; + } - utf8JavaByteArrayToUtf8Bytes(env, sql, &sql_bytes, NULL); - if (!sql_bytes) - { - return SQLITE_ERROR; - } + utf8JavaByteArrayToUtf8Bytes(env, sql, &sql_bytes, NULL); + if (!sql_bytes) + { + return SQLITE_ERROR; + } - status = sqlite3_exec(db, sql_bytes, 0, 0, NULL); - freeUtf8Bytes(sql_bytes); + status = sqlite3_exec(db, sql_bytes, 0, 0, NULL); + freeUtf8Bytes(sql_bytes); - if (status != SQLITE_OK) { - throwex_errorcode(env, this, status); - } + if (status != SQLITE_OK) { + throwex_errorcode(env, this, status); + } - return status; + return status; } -JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_errmsg_1utf8(JNIEnv* env, jobject this) +JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_errmsg_1utf8(JNIEnv *env, jobject this) { - sqlite3* db; - const char* str; + sqlite3 *db; + const char *str; - db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return NULL; - } + db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return NULL; + } - str = (const char*)sqlite3_errmsg(db); - if (!str) return NULL; - return utf8BytesToDirectByteBuffer(env, str, strlen(str)); + str = (const char*) sqlite3_errmsg(db); + if (!str) return NULL; + return utf8BytesToDirectByteBuffer(env, str, strlen(str)); } JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_libversion_1utf8( - JNIEnv* env, jobject this) + JNIEnv *env, jobject this) { - const char* version = sqlite3_libversion(); - return utf8BytesToDirectByteBuffer(env, version, strlen(version)); + const char* version = sqlite3_libversion(); + return utf8BytesToDirectByteBuffer(env, version, strlen(version)); } JNIEXPORT jlong JNICALL Java_org_sqlite_core_NativeDB_changes( - JNIEnv* env, jobject this) + JNIEnv *env, jobject this) { - sqlite3* db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return 0; - } + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return 0; + } - return sqlite3_changes(db); + return sqlite3_changes64(db); } JNIEXPORT jlong JNICALL Java_org_sqlite_core_NativeDB_total_1changes( - JNIEnv* env, jobject this) + JNIEnv *env, jobject this) { - sqlite3* db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return 0; - } + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return 0; + } - return sqlite3_total_changes(db); + return sqlite3_total_changes64(db); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_finalize( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_finalize(toref(stmt)); + return sqlite3_finalize(toref(stmt)); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_step( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_step(toref(stmt)); + return sqlite3_step(toref(stmt)); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_reset( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_reset(toref(stmt)); + return sqlite3_reset(toref(stmt)); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_clear_1bindings( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_clear_bindings(toref(stmt)); + return sqlite3_clear_bindings(toref(stmt)); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1parameter_1count( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_bind_parameter_count(toref(stmt)); + return sqlite3_bind_parameter_count(toref(stmt)); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_column_1count( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_column_count(toref(stmt)); + return sqlite3_column_count(toref(stmt)); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_column_1type( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_column_type(toref(stmt), col); + return sqlite3_column_type(toref(stmt), col); } JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_column_1decltype_1utf8( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - const char* str; + const char *str; - if (!stmt) - { - throwex_stmt_finalized(env); - return NULL; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return NULL; + } - str = (const char*)sqlite3_column_decltype(toref(stmt), col); - if (!str) return NULL; - return utf8BytesToDirectByteBuffer(env, str, strlen(str)); + str = (const char*) sqlite3_column_decltype(toref(stmt), col); + if (!str) return NULL; + return utf8BytesToDirectByteBuffer(env, str, strlen(str)); } JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_column_1table_1name_1utf8( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - const char* str; + const char *str; - if (!stmt) - { - throwex_stmt_finalized(env); - return NULL; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return NULL; + } - str = sqlite3_column_table_name(toref(stmt), col); - if (!str) return NULL; - return utf8BytesToDirectByteBuffer(env, str, strlen(str)); + str = sqlite3_column_table_name(toref(stmt), col); + if (!str) return NULL; + return utf8BytesToDirectByteBuffer(env, str, strlen(str)); } JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_column_1name_1utf8( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - const char* str; + const char *str; - if (!stmt) - { - throwex_stmt_finalized(env); - return NULL; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return NULL; + } - str = sqlite3_column_name(toref(stmt), col); - if (!str) return NULL; + str = sqlite3_column_name(toref(stmt), col); + if (!str) return NULL; - return utf8BytesToDirectByteBuffer(env, str, strlen(str)); + return utf8BytesToDirectByteBuffer(env, str, strlen(str)); } JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_column_1text_1utf8( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - sqlite3* db; - const char* bytes; - int nbytes; + sqlite3 *db; + const char *bytes; + int nbytes; - db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return NULL; - } + db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return NULL; + } - if (!stmt) - { - throwex_stmt_finalized(env); - return NULL; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return NULL; + } - bytes = (const char*)sqlite3_column_text(toref(stmt), col); - nbytes = sqlite3_column_bytes(toref(stmt), col); + bytes = (const char*) sqlite3_column_text(toref(stmt), col); + nbytes = sqlite3_column_bytes(toref(stmt), col); - if (!bytes && sqlite3_errcode(db) == SQLITE_NOMEM) - { - throwex_outofmemory(env); - return NULL; - } + if (!bytes && sqlite3_errcode(db) == SQLITE_NOMEM) + { + throwex_outofmemory(env); + return NULL; + } - return utf8BytesToDirectByteBuffer(env, bytes, nbytes); + return utf8BytesToDirectByteBuffer(env, bytes, nbytes); } JNIEXPORT jbyteArray JNICALL Java_org_sqlite_core_NativeDB_column_1blob( - JNIEnv* env, jobject this, jlong stmt, jint col) -{ - sqlite3* db; - int type; - int length; - jbyteArray jBlob; - const void* blob; - - db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return NULL; - } - - if (!stmt) - { - throwex_stmt_finalized(env); - return NULL; - } - - // The value returned by sqlite3_column_type() is only meaningful if no type conversions have occurred - type = sqlite3_column_type(toref(stmt), col); - blob = sqlite3_column_blob(toref(stmt), col); - if (!blob && sqlite3_errcode(db) == SQLITE_NOMEM) - { - throwex_outofmemory(env); - return NULL; - } - if (!blob) { - if (type == SQLITE_NULL) { - return NULL; - } - else { - // The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. - jBlob = (*env)->NewByteArray(env, 0); - if (!jBlob) { throwex_outofmemory(env); return NULL; } - return jBlob; - } - } - - length = sqlite3_column_bytes(toref(stmt), col); - jBlob = (*env)->NewByteArray(env, length); - if (!jBlob) { throwex_outofmemory(env); return NULL; } - - (*env)->SetByteArrayRegion(env, jBlob, (jsize)0, (jsize)length, (const jbyte*)blob); - - return jBlob; + JNIEnv *env, jobject this, jlong stmt, jint col) +{ + sqlite3 *db; + int type; + int length; + jbyteArray jBlob; + const void *blob; + + db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return NULL; + } + + if (!stmt) + { + throwex_stmt_finalized(env); + return NULL; + } + + // The value returned by sqlite3_column_type() is only meaningful if no type conversions have occurred + type = sqlite3_column_type(toref(stmt), col); + blob = sqlite3_column_blob(toref(stmt), col); + if (!blob && sqlite3_errcode(db) == SQLITE_NOMEM) + { + throwex_outofmemory(env); + return NULL; + } + if (!blob) { + if (type == SQLITE_NULL) { + return NULL; + } + else { + // The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. + jBlob = (*env)->NewByteArray(env, 0); + if (!jBlob) { throwex_outofmemory(env); return NULL; } + return jBlob; + } + } + + length = sqlite3_column_bytes(toref(stmt), col); + jBlob = (*env)->NewByteArray(env, length); + if (!jBlob) { throwex_outofmemory(env); return NULL; } + + (*env)->SetByteArrayRegion(env, jBlob, (jsize) 0, (jsize) length, (const jbyte*) blob); + + return jBlob; } JNIEXPORT jdouble JNICALL Java_org_sqlite_core_NativeDB_column_1double( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - if (!stmt) - { - throwex_stmt_finalized(env); - return 0; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return 0; + } - return sqlite3_column_double(toref(stmt), col); + return sqlite3_column_double(toref(stmt), col); } JNIEXPORT jlong JNICALL Java_org_sqlite_core_NativeDB_column_1long( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - if (!stmt) - { - throwex_stmt_finalized(env); - return 0; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return 0; + } - return sqlite3_column_int64(toref(stmt), col); + return sqlite3_column_int64(toref(stmt), col); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_column_1int( - JNIEnv* env, jobject this, jlong stmt, jint col) + JNIEnv *env, jobject this, jlong stmt, jint col) { - if (!stmt) - { - throwex_stmt_finalized(env); - return 0; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return 0; + } - return sqlite3_column_int(toref(stmt), col); + return sqlite3_column_int(toref(stmt), col); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1null( - JNIEnv* env, jobject this, jlong stmt, jint pos) + JNIEnv *env, jobject this, jlong stmt, jint pos) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_bind_null(toref(stmt), pos); + return sqlite3_bind_null(toref(stmt), pos); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1int( - JNIEnv* env, jobject this, jlong stmt, jint pos, jint v) + JNIEnv *env, jobject this, jlong stmt, jint pos, jint v) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_bind_int(toref(stmt), pos, v); + return sqlite3_bind_int(toref(stmt), pos, v); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1long( - JNIEnv* env, jobject this, jlong stmt, jint pos, jlong v) + JNIEnv *env, jobject this, jlong stmt, jint pos, jlong v) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_bind_int64(toref(stmt), pos, v); + return sqlite3_bind_int64(toref(stmt), pos, v); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1double( - JNIEnv* env, jobject this, jlong stmt, jint pos, jdouble v) + JNIEnv *env, jobject this, jlong stmt, jint pos, jdouble v) { - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - return sqlite3_bind_double(toref(stmt), pos, v); + return sqlite3_bind_double(toref(stmt), pos, v); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1text_1utf8( - JNIEnv* env, jobject this, jlong stmt, jint pos, jbyteArray v) + JNIEnv *env, jobject this, jlong stmt, jint pos, jbyteArray v) { - int rc; - char* v_bytes; - int v_nbytes; + int rc; + char* v_bytes; + int v_nbytes; - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - utf8JavaByteArrayToUtf8Bytes(env, v, &v_bytes, &v_nbytes); - if (!v_bytes) return SQLITE_ERROR; + utf8JavaByteArrayToUtf8Bytes(env, v, &v_bytes, &v_nbytes); + if (!v_bytes) return SQLITE_ERROR; - rc = sqlite3_bind_text(toref(stmt), pos, v_bytes, v_nbytes, SQLITE_TRANSIENT); - freeUtf8Bytes(v_bytes); + rc = sqlite3_bind_text(toref(stmt), pos, v_bytes, v_nbytes, SQLITE_TRANSIENT); + freeUtf8Bytes(v_bytes); - return rc; + return rc; } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_bind_1blob( - JNIEnv* env, jobject this, jlong stmt, jint pos, jbyteArray v) + JNIEnv *env, jobject this, jlong stmt, jint pos, jbyteArray v) { - jint rc; - void* a; - jsize size; + jint rc; + void *a; + jsize size; - if (!stmt) - { - throwex_stmt_finalized(env); - return SQLITE_MISUSE; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return SQLITE_MISUSE; + } - size = (*env)->GetArrayLength(env, v); - a = (*env)->GetPrimitiveArrayCritical(env, v, 0); - if (!a) { throwex_outofmemory(env); return 0; } - rc = sqlite3_bind_blob(toref(stmt), pos, a, size, SQLITE_TRANSIENT); - (*env)->ReleasePrimitiveArrayCritical(env, v, a, JNI_ABORT); - return rc; + size = (*env)->GetArrayLength(env, v); + a = (*env)->GetPrimitiveArrayCritical(env, v, 0); + if (!a) { throwex_outofmemory(env); return 0; } + rc = sqlite3_bind_blob(toref(stmt), pos, a, size, SQLITE_TRANSIENT); + (*env)->ReleasePrimitiveArrayCritical(env, v, a, JNI_ABORT); + return rc; } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1null( - JNIEnv* env, jobject this, jlong context) + JNIEnv *env, jobject this, jlong context) { - if (!context) return; - sqlite3_result_null(toref(context)); + if (!context) return; + sqlite3_result_null(toref(context)); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1text_1utf8( - JNIEnv* env, jobject this, jlong context, jbyteArray value) + JNIEnv *env, jobject this, jlong context, jbyteArray value) { - char* value_bytes; - int value_nbytes; + char* value_bytes; + int value_nbytes; - if (!context) return; - if (value == NULL) { sqlite3_result_null(toref(context)); return; } + if (!context) return; + if (value == NULL) { sqlite3_result_null(toref(context)); return; } - utf8JavaByteArrayToUtf8Bytes(env, value, &value_bytes, &value_nbytes); - if (!value_bytes) - { - sqlite3_result_error_nomem(toref(context)); - return; - } + utf8JavaByteArrayToUtf8Bytes(env, value, &value_bytes, &value_nbytes); + if (!value_bytes) + { + sqlite3_result_error_nomem(toref(context)); + return; + } - sqlite3_result_text(toref(context), value_bytes, value_nbytes, SQLITE_TRANSIENT); - freeUtf8Bytes(value_bytes); + sqlite3_result_text(toref(context), value_bytes, value_nbytes, SQLITE_TRANSIENT); + freeUtf8Bytes(value_bytes); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1blob( - JNIEnv* env, jobject this, jlong context, jobject value) + JNIEnv *env, jobject this, jlong context, jobject value) { - jbyte* bytes; - jsize size; + jbyte *bytes; + jsize size; - if (!context) return; - if (value == NULL) { sqlite3_result_null(toref(context)); return; } + if (!context) return; + if (value == NULL) { sqlite3_result_null(toref(context)); return; } - size = (*env)->GetArrayLength(env, value); - bytes = (*env)->GetPrimitiveArrayCritical(env, value, 0); - if (!bytes) { throwex_outofmemory(env); return; } - sqlite3_result_blob(toref(context), bytes, size, SQLITE_TRANSIENT); - (*env)->ReleasePrimitiveArrayCritical(env, value, bytes, JNI_ABORT); + size = (*env)->GetArrayLength(env, value); + bytes = (*env)->GetPrimitiveArrayCritical(env, value, 0); + if (!bytes) { throwex_outofmemory(env); return; } + sqlite3_result_blob(toref(context), bytes, size, SQLITE_TRANSIENT); + (*env)->ReleasePrimitiveArrayCritical(env, value, bytes, JNI_ABORT); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1double( - JNIEnv* env, jobject this, jlong context, jdouble value) + JNIEnv *env, jobject this, jlong context, jdouble value) { - if (!context) return; - sqlite3_result_double(toref(context), value); + if (!context) return; + sqlite3_result_double(toref(context), value); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1long( - JNIEnv* env, jobject this, jlong context, jlong value) + JNIEnv *env, jobject this, jlong context, jlong value) { - if (!context) return; - sqlite3_result_int64(toref(context), value); + if (!context) return; + sqlite3_result_int64(toref(context), value); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1int( - JNIEnv* env, jobject this, jlong context, jint value) + JNIEnv *env, jobject this, jlong context, jint value) { - if (!context) return; - sqlite3_result_int(toref(context), value); + if (!context) return; + sqlite3_result_int(toref(context), value); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_result_1error_1utf8( - JNIEnv* env, jobject this, jlong context, jbyteArray err) + JNIEnv *env, jobject this, jlong context, jbyteArray err) { - char* err_bytes; - int err_nbytes; + char* err_bytes; + int err_nbytes; - if (!context) return; + if (!context) return; - utf8JavaByteArrayToUtf8Bytes(env, err, &err_bytes, &err_nbytes); - if (!err_bytes) - { - sqlite3_result_error_nomem(toref(context)); - return; - } + utf8JavaByteArrayToUtf8Bytes(env, err, &err_bytes, &err_nbytes); + if (!err_bytes) + { + sqlite3_result_error_nomem(toref(context)); + return; + } - sqlite3_result_error(toref(context), err_bytes, err_nbytes); - freeUtf8Bytes(err_bytes); + sqlite3_result_error(toref(context), err_bytes, err_nbytes); + freeUtf8Bytes(err_bytes); } JNIEXPORT jobject JNICALL Java_org_sqlite_core_NativeDB_value_1text_1utf8( - JNIEnv* env, jobject this, jobject f, jint arg) + JNIEnv *env, jobject this, jobject f, jint arg) { - const char* bytes; - int nbytes; + const char* bytes; + int nbytes; - sqlite3_value* value = tovalue(env, f, arg); - if (!value) return NULL; + sqlite3_value *value = tovalue(env, f, arg); + if (!value) return NULL; - bytes = (const char*)sqlite3_value_text(value); - nbytes = sqlite3_value_bytes(value); + bytes = (const char*) sqlite3_value_text(value); + nbytes = sqlite3_value_bytes(value); - return utf8BytesToDirectByteBuffer(env, bytes, nbytes); + return utf8BytesToDirectByteBuffer(env, bytes, nbytes); } JNIEXPORT jbyteArray JNICALL Java_org_sqlite_core_NativeDB_value_1blob( - JNIEnv* env, jobject this, jobject f, jint arg) + JNIEnv *env, jobject this, jobject f, jint arg) { - int length; - jbyteArray jBlob; - const void* blob; - sqlite3_value* value = tovalue(env, f, arg); - if (!value) return NULL; + int length; + jbyteArray jBlob; + const void *blob; + sqlite3_value *value = tovalue(env, f, arg); + if (!value) return NULL; - blob = sqlite3_value_blob(value); - if (!blob) return NULL; + blob = sqlite3_value_blob(value); + if (!blob) return NULL; - length = sqlite3_value_bytes(value); - jBlob = (*env)->NewByteArray(env, length); - if (!jBlob) { throwex_outofmemory(env); return NULL; } + length = sqlite3_value_bytes(value); + jBlob = (*env)->NewByteArray(env, length); + if (!jBlob) { throwex_outofmemory(env); return NULL; } - (*env)->SetByteArrayRegion(env, jBlob, (jsize)0, (jsize)length, (const jbyte*)blob); + (*env)->SetByteArrayRegion(env, jBlob, (jsize) 0, (jsize) length, (const jbyte*) blob); - return jBlob; + return jBlob; } JNIEXPORT jdouble JNICALL Java_org_sqlite_core_NativeDB_value_1double( - JNIEnv* env, jobject this, jobject f, jint arg) + JNIEnv *env, jobject this, jobject f, jint arg) { - sqlite3_value* value = tovalue(env, f, arg); - return value ? sqlite3_value_double(value) : 0; + sqlite3_value *value = tovalue(env, f, arg); + return value ? sqlite3_value_double(value) : 0; } JNIEXPORT jlong JNICALL Java_org_sqlite_core_NativeDB_value_1long( - JNIEnv* env, jobject this, jobject f, jint arg) + JNIEnv *env, jobject this, jobject f, jint arg) { - sqlite3_value* value = tovalue(env, f, arg); - return value ? sqlite3_value_int64(value) : 0; + sqlite3_value *value = tovalue(env, f, arg); + return value ? sqlite3_value_int64(value) : 0; } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_value_1int( - JNIEnv* env, jobject this, jobject f, jint arg) + JNIEnv *env, jobject this, jobject f, jint arg) { - sqlite3_value* value = tovalue(env, f, arg); - return value ? sqlite3_value_int(value) : 0; + sqlite3_value *value = tovalue(env, f, arg); + return value ? sqlite3_value_int(value) : 0; } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_value_1type( - JNIEnv* env, jobject this, jobject func, jint arg) + JNIEnv *env, jobject this, jobject func, jint arg) { - return sqlite3_value_type(tovalue(env, func, arg)); + return sqlite3_value_type(tovalue(env, func, arg)); } -void free_collation_func(void* context) { - JNIEnv* env; - struct CollationData* coll = (struct CollationData*)context; - (*coll->vm)->AttachCurrentThread(coll->vm, (void**)&env, 0); +void free_collation_func(void *context) { + JNIEnv *env; + struct CollationData *coll = (struct CollationData*)context; + (*coll->vm)->AttachCurrentThread(coll->vm, (void **)&env, 0); - (*env)->DeleteGlobalRef(env, coll->func); - free(coll); + (*env)->DeleteGlobalRef(env, coll->func); + free(coll); } -void free_udf_func(void* udfToFree) { - JNIEnv* env; - struct UDFData* udf = (struct UDFData*)udfToFree; - (*udf->vm)->AttachCurrentThread(udf->vm, (void**)&env, 0); +void free_udf_func(void *udfToFree) { + JNIEnv *env; + struct UDFData *udf = (struct UDFData*) udfToFree; + (*udf->vm)->AttachCurrentThread(udf->vm, (void **)&env, 0); - (*env)->DeleteGlobalRef(env, udf->func); - free(udf); + (*env)->DeleteGlobalRef(env, udf->func); + free(udf); } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_create_1function_1utf8( - JNIEnv* env, jobject nativeDB, jbyteArray name, jobject func, jint nArgs, jint flags) -{ - jint ret = 0; - char* name_bytes; - int isAgg = 0, isWindow = 0; - - struct UDFData* udf = (struct UDFData*)malloc(sizeof(struct UDFData)); - - if (!udf) { throwex_outofmemory(env); return 0; } - - isAgg = (*env)->IsInstanceOf(env, func, aclass); - isWindow = (*env)->IsInstanceOf(env, func, wclass); - udf->func = (*env)->NewGlobalRef(env, func); - (*env)->GetJavaVM(env, &udf->vm); - - utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); - if (!name_bytes) { throwex_outofmemory(env); return 0; } - - if (isAgg) { - ret = sqlite3_create_window_function( - gethandle(env, nativeDB), - name_bytes, // function name - nArgs, // number of args - SQLITE_UTF16 | flags, // preferred chars - udf, - &xStep, - &xFinal, - isWindow ? &xValue : NULL, - isWindow ? &xInverse : NULL, - &free_udf_func // Cleanup function - ); - } - else { - ret = sqlite3_create_function_v2( - gethandle(env, nativeDB), - name_bytes, // function name - nArgs, // number of args - SQLITE_UTF16 | flags, // preferred chars - udf, - &xFunc, - NULL, - NULL, - &free_udf_func // Cleanup function - ); - } - - freeUtf8Bytes(name_bytes); - - return ret; + JNIEnv *env, jobject nativeDB, jbyteArray name, jobject func, jint nArgs, jint flags) +{ + jint ret = 0; + char *name_bytes; + int isAgg = 0, isWindow = 0; + + struct UDFData *udf = (struct UDFData*) malloc(sizeof(struct UDFData)); + + if (!udf) { throwex_outofmemory(env); return 0; } + + isAgg = (*env)->IsInstanceOf(env, func, aclass); + isWindow = (*env)->IsInstanceOf(env, func, wclass); + udf->func = (*env)->NewGlobalRef(env, func); + (*env)->GetJavaVM(env, &udf->vm); + + utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); + if (!name_bytes) { throwex_outofmemory(env); return 0; } + + if (isAgg) { + ret = sqlite3_create_window_function( + gethandle(env, nativeDB), + name_bytes, // function name + nArgs, // number of args + SQLITE_UTF16 | flags, // preferred chars + udf, + &xStep, + &xFinal, + isWindow ? &xValue : NULL, + isWindow ? &xInverse : NULL, + &free_udf_func // Cleanup function + ); + } else { + ret = sqlite3_create_function_v2( + gethandle(env, nativeDB), + name_bytes, // function name + nArgs, // number of args + SQLITE_UTF16 | flags, // preferred chars + udf, + &xFunc, + NULL, + NULL, + &free_udf_func // Cleanup function + ); + } + + freeUtf8Bytes(name_bytes); + + return ret; } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_destroy_1function_1utf8( - JNIEnv* env, jobject nativeDB, jbyteArray name) + JNIEnv *env, jobject nativeDB, jbyteArray name) { - jint ret = 0; - char* name_bytes; + jint ret = 0; + char* name_bytes; - utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); - if (!name_bytes) { throwex_outofmemory(env); return 0; } + utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); + if (!name_bytes) { throwex_outofmemory(env); return 0; } - ret = sqlite3_create_function( - gethandle(env, nativeDB), name_bytes, -1, SQLITE_UTF16, NULL, NULL, NULL, NULL - ); - freeUtf8Bytes(name_bytes); + ret = sqlite3_create_function( + gethandle(env, nativeDB), name_bytes, -1, SQLITE_UTF16, NULL, NULL, NULL, NULL + ); + freeUtf8Bytes(name_bytes); - return ret; + return ret; } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_create_1collation_1utf8( - JNIEnv* env, jobject this, jbyteArray name, jobject func) + JNIEnv *env, jobject this, jbyteArray name, jobject func) { - jint ret = 0; - char* name_bytes; + jint ret = 0; + char *name_bytes; - struct CollationData* coll = (struct CollationData*)malloc(sizeof(struct CollationData)); + struct CollationData *coll = (struct CollationData*) malloc(sizeof(struct CollationData)); - if (!coll) { throwex_outofmemory(env); return 0; } + if (!coll) { throwex_outofmemory(env); return 0; } - coll->func = (*env)->NewGlobalRef(env, func); - (*env)->GetJavaVM(env, &coll->vm); + coll->func = (*env)->NewGlobalRef(env, func); + (*env)->GetJavaVM(env, &coll->vm); - utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); - if (!name_bytes) { throwex_outofmemory(env); return 0; } + utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); + if (!name_bytes) { throwex_outofmemory(env); return 0; } - ret = sqlite3_create_collation_v2( - gethandle(env, this), - name_bytes, // collation name - SQLITE_UTF16, // preferred chars - coll, - &xCompare, - &free_collation_func - ); + ret = sqlite3_create_collation_v2( + gethandle(env, this), + name_bytes, // collation name + SQLITE_UTF16, // preferred chars + coll, + &xCompare, + &free_collation_func + ); - freeUtf8Bytes(name_bytes); + freeUtf8Bytes(name_bytes); - return ret; + return ret; } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_destroy_1collation_1utf8( - JNIEnv* env, jobject this, jbyteArray name) + JNIEnv *env, jobject this, jbyteArray name) { - jint ret = 0; - char* name_bytes; + jint ret = 0; + char *name_bytes; - utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); - if (!name_bytes) { throwex_outofmemory(env); return 0; } + utf8JavaByteArrayToUtf8Bytes(env, name, &name_bytes, NULL); + if (!name_bytes) { throwex_outofmemory(env); return 0; } - ret = sqlite3_create_collation( - gethandle(env, this), name_bytes, SQLITE_UTF16, 0, 0 - ); - freeUtf8Bytes(name_bytes); + ret = sqlite3_create_collation( + gethandle(env, this), name_bytes, SQLITE_UTF16, 0, 0 + ); + freeUtf8Bytes(name_bytes); - return ret; + return ret; } -JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_limit(JNIEnv* env, jobject this, jint id, jint value) +JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_limit(JNIEnv *env, jobject this, jint id, jint value) { - sqlite3* db; + sqlite3* db; - db = gethandle(env, this); + db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return 0; - } + if (!db) + { + throwex_db_closed(env); + return 0; + } - return sqlite3_limit(db, id, value); + return sqlite3_limit(db, id, value); } // COMPOUND FUNCTIONS /////////////////////////////////////////////// JNIEXPORT jobjectArray JNICALL Java_org_sqlite_core_NativeDB_column_1metadata( - JNIEnv* env, jobject this, jlong stmt) + JNIEnv *env, jobject this, jlong stmt) { - const char* zTableName, * zColumnName; - int pNotNull, pPrimaryKey, pAutoinc, i, colCount; - jobjectArray array; - jbooleanArray colData; - jboolean* colDataRaw; - sqlite3* db; - sqlite3_stmt* dbstmt; + const char *zTableName, *zColumnName; + int pNotNull, pPrimaryKey, pAutoinc, i, colCount; + jobjectArray array; + jbooleanArray colData; + jboolean* colDataRaw; + sqlite3 *db; + sqlite3_stmt *dbstmt; - db = gethandle(env, this); - if (!db) - { - throwex_db_closed(env); - return NULL; - } + db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return NULL; + } - if (!stmt) - { - throwex_stmt_finalized(env); - return NULL; - } + if (!stmt) + { + throwex_stmt_finalized(env); + return NULL; + } - dbstmt = toref(stmt); + dbstmt = toref(stmt); - colCount = sqlite3_column_count(dbstmt); - array = (*env)->NewObjectArray( - env, colCount, (*env)->FindClass(env, "[Z"), NULL); - if (!array) { throwex_outofmemory(env); return 0; } + colCount = sqlite3_column_count(dbstmt); + array = (*env)->NewObjectArray(env, colCount, bool_array_class, NULL); + if (!array) { throwex_outofmemory(env); return 0; } - colDataRaw = (jboolean*)malloc(3 * sizeof(jboolean)); - if (!colDataRaw) { throwex_outofmemory(env); return 0; } + colDataRaw = (jboolean*)malloc(3 * sizeof(jboolean)); + if (!colDataRaw) { throwex_outofmemory(env); return 0; } - for (i = 0; i < colCount; i++) { - // load passed column name and table name - zColumnName = sqlite3_column_name(dbstmt, i); - zTableName = sqlite3_column_table_name(dbstmt, i); + for (i = 0; i < colCount; i++) { + // load passed column name and table name + zColumnName = sqlite3_column_name(dbstmt, i); + zTableName = sqlite3_column_table_name(dbstmt, i); - pNotNull = 0; - pPrimaryKey = 0; - pAutoinc = 0; + pNotNull = 0; + pPrimaryKey = 0; + pAutoinc = 0; - // request metadata for column and load into output variables - if (zTableName && zColumnName) { - sqlite3_table_column_metadata( - db, 0, zTableName, zColumnName, - 0, 0, &pNotNull, &pPrimaryKey, &pAutoinc - ); - } + // request metadata for column and load into output variables + if (zTableName && zColumnName) { + sqlite3_table_column_metadata( + db, 0, zTableName, zColumnName, + 0, 0, &pNotNull, &pPrimaryKey, &pAutoinc + ); + } - // load relevant metadata into 2nd dimension of return results - colDataRaw[0] = pNotNull; - colDataRaw[1] = pPrimaryKey; - colDataRaw[2] = pAutoinc; + // load relevant metadata into 2nd dimension of return results + colDataRaw[0] = pNotNull; + colDataRaw[1] = pPrimaryKey; + colDataRaw[2] = pAutoinc; - colData = (*env)->NewBooleanArray(env, 3); - if (!colData) { throwex_outofmemory(env); return 0; } + colData = (*env)->NewBooleanArray(env, 3); + if (!colData) { throwex_outofmemory(env); return 0; } - (*env)->SetBooleanArrayRegion(env, colData, 0, 3, colDataRaw); - (*env)->SetObjectArrayElement(env, array, i, colData); - } + (*env)->SetBooleanArrayRegion(env, colData, 0, 3, colDataRaw); + (*env)->SetObjectArrayElement(env, array, i, colData); + } - free(colDataRaw); + free(colDataRaw); - return array; + return array; } // backup function void reportProgress(JNIEnv* env, jobject func, int remaining, int pageCount) { - if (!func) - return; + if(!func) + return; - (*env)->CallVoidMethod(env, func, pmethod, remaining, pageCount); + (*env)->CallVoidMethod(env, func, pobserver_mth_progress, remaining, pageCount); } +void updateProgress(JNIEnv *env, sqlite3_backup *pBackup, jobject progress) { + if (!progress) + return; + int remaining = sqlite3_backup_remaining(pBackup); + int pagecount = sqlite3_backup_pagecount(pBackup); + (*env)->CallVoidMethod(env, progress, pobserver_mth_progress, remaining, pagecount); +} + +void copyLoop(JNIEnv *env, sqlite3_backup *pBackup, jobject progress, + int pagesPerStep, int nTimeoutLimit, int sleepTimeMillis) { + int rc; + int nTimeout = 0; + + do { + rc = sqlite3_backup_step(pBackup, pagesPerStep); + + // if the step completed successfully, update progress + if (rc == SQLITE_OK || rc == SQLITE_DONE) { + updateProgress(env, pBackup, progress); + } + + if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { + if (nTimeout++ >= nTimeoutLimit) + break; + sqlite3_sleep(sleepTimeMillis); + } + } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); +} /* ** Perform an online backup of database pDb to the database file named -** by zFilename. This function copies 5 database pages from pDb to -** zFilename, then unlocks pDb and sleeps for 250 ms, then repeats the -** process until the entire database is backed up. +** by zFilename. This function copies pagesPerStep database pages from pDb to +** zFilename per step. If the backup step returns SQLITE_BUSY or SQLITE_LOCKED, +** the function waits nTimeoutLimit milliseconds before trying again. Should +** this occur more than nTimeoutLimit times, the backup/restore will fail and +** the corresponding error code is returned. If any other return code is +** returned during the copy, the backup/restore is aborted, and error is +** returned. ** ** The third argument passed to this function must be a pointer to a progress -** function. After each set of 5 pages is backed up, the progress function +** function or null. After each set of pages is backed up, the progress function ** is invoked with two integer parameters: the number of pages left to ** copy, and the total number of pages in the source file. This information ** may be used, for example, to update a GUI progress bar. @@ -1485,146 +1544,145 @@ void reportProgress(JNIEnv* env, jobject func, int remaining, int pageCount) { ** If the backup process is successfully completed, SQLITE_OK is returned. ** Otherwise, if an error occurs, an SQLite error code is returned. */ - JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_backup( - JNIEnv* env, jobject this, - jbyteArray zDBName, - jbyteArray zFilename, /* Name of file to back up to */ - jobject observer /* Progress function to invoke */ + JNIEnv *env, jobject this, + jbyteArray zDBName, + jbyteArray zFilename, /* Name of file to back up to */ + jobject observer, /* Progress function to invoke */ + jint sleepTimeMillis, /* number of milliseconds to sleep if DB is busy */ + jint nTimeoutLimit, /* max number of SQLite Busy return codes before failing */ + jint pagesPerStep /* number of DB pages to copy per step */ ) { #if SQLITE_VERSION_NUMBER >= 3006011 - int rc; /* Function return code */ - sqlite3* pDb; /* Database to back up */ - sqlite3* pFile; /* Database connection opened on zFilename */ - sqlite3_backup* pBackup; /* Backup handle used to copy data */ - char* dFileName; - char* dDBName; - - pDb = gethandle(env, this); - if (!pDb) - { - throwex_db_closed(env); - return SQLITE_MISUSE; - } - - utf8JavaByteArrayToUtf8Bytes(env, zFilename, &dFileName, NULL); - if (!dFileName) - { - return SQLITE_NOMEM; - } - - utf8JavaByteArrayToUtf8Bytes(env, zDBName, &dDBName, NULL); - if (!dDBName) - { - freeUtf8Bytes(dFileName); - return SQLITE_NOMEM; - } - - /* Open the database file identified by dFileName. */ - int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; - if (sqlite3_strnicmp(dFileName, "file:", 5) == 0) { - flags |= SQLITE_OPEN_URI; - } - rc = sqlite3_open_v2(dFileName, &pFile, flags, NULL); - - if (rc == SQLITE_OK) { - - /* Open the sqlite3_backup object used to accomplish the transfer */ - pBackup = sqlite3_backup_init(pFile, "main", pDb, dDBName); - if (pBackup) { - while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK) {} - - /* Release resources allocated by backup_init(). */ - (void)sqlite3_backup_finish(pBackup); - } - rc = sqlite3_errcode(pFile); - } - - /* Close the database connection opened on database file zFilename - ** and return the result of this function. */ - (void)sqlite3_close(pFile); - - freeUtf8Bytes(dDBName); - freeUtf8Bytes(dFileName); - - return rc; + int rc; /* Function return code */ + sqlite3* pDb; /* Database to back up */ + sqlite3* pFile; /* Database connection opened on zFilename */ + sqlite3_backup *pBackup; /* Backup handle used to copy data */ + char *dFileName; + char *dDBName; + + pDb = gethandle(env, this); + if (!pDb) + { + throwex_db_closed(env); + return SQLITE_MISUSE; + } + + utf8JavaByteArrayToUtf8Bytes(env, zFilename, &dFileName, NULL); + if (!dFileName) + { + return SQLITE_NOMEM; + } + + utf8JavaByteArrayToUtf8Bytes(env, zDBName, &dDBName, NULL); + if (!dDBName) + { + freeUtf8Bytes(dFileName); + return SQLITE_NOMEM; + } + + /* Open the database file identified by dFileName. */ + int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + if (sqlite3_strnicmp(dFileName, "file:", 5) == 0) { + flags |= SQLITE_OPEN_URI; + } + rc = sqlite3_open_v2(dFileName, &pFile, flags, NULL); + + if(rc == SQLITE_OK) { + + /* Open the sqlite3_backup object used to accomplish the transfer */ + pBackup = sqlite3_backup_init(pFile, "main", pDb, dDBName); + if( pBackup ){ + copyLoop(env, pBackup, observer, pagesPerStep, nTimeoutLimit, sleepTimeMillis); + + /* Release resources allocated by backup_init(). */ + (void)sqlite3_backup_finish(pBackup); + } + rc = sqlite3_errcode(pFile); + } + + /* Close the database connection opened on database file zFilename + ** and return the result of this function. */ + (void)sqlite3_close(pFile); + + freeUtf8Bytes(dDBName); + freeUtf8Bytes(dFileName); + + return rc; #else - return SQLITE_INTERNAL; + return SQLITE_INTERNAL; #endif } JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_restore( - JNIEnv* env, jobject this, - jbyteArray zDBName, - jbyteArray zFilename, /* Name of file to back up to */ - jobject observer /* Progress function to invoke */ + JNIEnv *env, jobject this, + jbyteArray zDBName, + jbyteArray zFilename, /* Name of file to restore from */ + jobject observer, /* Progress function to invoke */ + jint sleepTimeMillis, /* number of milliseconds to sleep if DB is busy */ + jint nTimeoutLimit, /* max number of SQLite Busy return codes before failing */ + jint pagesPerStep /* number of DB pages to copy per step */ ) { #if SQLITE_VERSION_NUMBER >= 3006011 - int rc; /* Function return code */ - sqlite3* pDb; /* Database to back up */ - sqlite3* pFile; /* Database connection opened on zFilename */ - sqlite3_backup* pBackup; /* Backup handle used to copy data */ - char* dFileName; - char* dDBName; - int nTimeout = 0; - - pDb = gethandle(env, this); - if (!pDb) - { - throwex_db_closed(env); - return SQLITE_MISUSE; - } - - utf8JavaByteArrayToUtf8Bytes(env, zFilename, &dFileName, NULL); - if (!dFileName) - { - return SQLITE_NOMEM; - } - - utf8JavaByteArrayToUtf8Bytes(env, zDBName, &dDBName, NULL); - if (!dDBName) - { - freeUtf8Bytes(dFileName); - return SQLITE_NOMEM; - } - - /* Open the database file identified by dFileName. */ - int flags = SQLITE_OPEN_READONLY; - if (sqlite3_strnicmp(dFileName, "file:", 5) == 0) { - flags |= SQLITE_OPEN_URI; - } - rc = sqlite3_open_v2(dFileName, &pFile, flags, NULL); - - if (rc == SQLITE_OK) { - - /* Open the sqlite3_backup object used to accomplish the transfer */ - pBackup = sqlite3_backup_init(pDb, dDBName, pFile, "main"); - if (pBackup) { - while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK - || rc == SQLITE_BUSY) { - if (rc == SQLITE_BUSY) { - if (nTimeout++ >= 3) break; - sqlite3_sleep(100); - } - } - /* Release resources allocated by backup_init(). */ - (void)sqlite3_backup_finish(pBackup); - } - rc = sqlite3_errcode(pFile); - } - - /* Close the database connection opened on database file zFilename - ** and return the result of this function. */ - (void)sqlite3_close(pFile); - - freeUtf8Bytes(dDBName); - freeUtf8Bytes(dFileName); - - return rc; + int rc; /* Function return code */ + sqlite3* pDb; /* Database to back up */ + sqlite3* pFile; /* Database connection opened on zFilename */ + sqlite3_backup *pBackup; /* Backup handle used to copy data */ + char *dFileName; + char *dDBName; + int nTimeout = 0; + + pDb = gethandle(env, this); + if (!pDb) + { + throwex_db_closed(env); + return SQLITE_MISUSE; + } + + utf8JavaByteArrayToUtf8Bytes(env, zFilename, &dFileName, NULL); + if (!dFileName) + { + return SQLITE_NOMEM; + } + + utf8JavaByteArrayToUtf8Bytes(env, zDBName, &dDBName, NULL); + if (!dDBName) + { + freeUtf8Bytes(dFileName); + return SQLITE_NOMEM; + } + + /* Open the database file identified by dFileName. */ + int flags = SQLITE_OPEN_READONLY; + if (sqlite3_strnicmp(dFileName, "file:", 5) == 0) { + flags |= SQLITE_OPEN_URI; + } + rc = sqlite3_open_v2(dFileName, &pFile, flags, NULL); + + if (rc == SQLITE_OK) { + + /* Open the sqlite3_backup object used to accomplish the transfer */ + pBackup = sqlite3_backup_init(pDb, dDBName, pFile, "main"); + if (pBackup) { + copyLoop(env, pBackup, observer, pagesPerStep, nTimeoutLimit, sleepTimeMillis); + /* Release resources allocated by backup_init(). */ + (void)sqlite3_backup_finish(pBackup); + } + rc = sqlite3_errcode(pFile); + } + + /* Close the database connection opened on database file zFilename + ** and return the result of this function. */ + (void)sqlite3_close(pFile); + + freeUtf8Bytes(dDBName); + freeUtf8Bytes(dFileName); + + return rc; #else - return SQLITE_INTERNAL; + return SQLITE_INTERNAL; #endif } @@ -1632,190 +1690,277 @@ JNIEXPORT jint JNICALL Java_org_sqlite_core_NativeDB_restore( // Progress handler struct ProgressHandlerContext { - JavaVM* vm; - jmethodID mth; - jobject phandler; + JavaVM *vm; + jobject phandler; }; -static void free_progress_handler(JNIEnv* env, void* toFree) { - struct ProgressHandlerContext* progressHandlerContext = (struct ProgressHandlerContext*)toFree; - (*env)->DeleteGlobalRef(env, progressHandlerContext->phandler); - free(toFree); +static void free_progress_handler(JNIEnv *env, void *toFree) { + struct ProgressHandlerContext* progressHandlerContext = (struct ProgressHandlerContext*) toFree; + (*env)->DeleteGlobalRef(env, progressHandlerContext->phandler); + free(toFree); } -static int progress_handler_function(void* ctx) { - JNIEnv* env = 0; - struct ProgressHandlerContext* progressHandlerContext = (struct ProgressHandlerContext*)ctx; - (*progressHandlerContext->vm)->AttachCurrentThread(progressHandlerContext->vm, (void**)&env, 0); - jint rv = (*env)->CallIntMethod(env, progressHandlerContext->phandler, progressHandlerContext->mth); - return rv; +static int progress_handler_function(void *ctx) { + JNIEnv *env = 0; + struct ProgressHandlerContext* progressHandlerContext = (struct ProgressHandlerContext*) ctx; + (*progressHandlerContext->vm)->AttachCurrentThread(progressHandlerContext->vm, (void **)&env, 0); + jint rv = (*env)->CallIntMethod(env, progressHandlerContext->phandler, phandle_mth_progress); + return rv; } -static void change_progress_handler(JNIEnv* env, jobject nativeDB, jobject progressHandler, jint vmCalls) +static void change_progress_handler(JNIEnv *env, jobject nativeDB, jobject progressHandler, jint vmCalls) { - sqlite3* db; + sqlite3 *db; - db = gethandle(env, nativeDB); - if (!db) { - throwex_db_closed(env); - return; - } + db = gethandle(env, nativeDB); + if (!db){ + throwex_db_closed(env); + return; + } - struct ProgressHandlerContext* progressHandlerContext = NULL; + struct ProgressHandlerContext* progressHandlerContext = NULL; - if (progressHandler) { - progressHandlerContext = (struct ProgressHandlerContext*)malloc(sizeof(struct ProgressHandlerContext)); - (*env)->GetJavaVM(env, &progressHandlerContext->vm); + if (progressHandler) { + progressHandlerContext = (struct ProgressHandlerContext*) malloc(sizeof(struct ProgressHandlerContext)); + (*env)->GetJavaVM(env, &progressHandlerContext->vm); - progressHandlerContext->phandler = (*env)->NewGlobalRef(env, progressHandler); - progressHandlerContext->mth = (*env)->GetMethodID(env, - (*env)->GetObjectClass(env, progressHandlerContext->phandler), - "progress", - "()I"); - } + progressHandlerContext->phandler = (*env)->NewGlobalRef(env, progressHandler); + } - if (progressHandlerContext) { - sqlite3_progress_handler(gethandle(env, nativeDB), vmCalls, &progress_handler_function, progressHandlerContext); - } - else { - sqlite3_progress_handler(gethandle(env, nativeDB), 0, NULL, NULL); - } + if (progressHandlerContext) { + sqlite3_progress_handler(gethandle(env, nativeDB), vmCalls, &progress_handler_function, progressHandlerContext); + } else { + sqlite3_progress_handler(gethandle(env, nativeDB), 0, NULL, NULL); + } - set_new_handler(env, nativeDB, "progressHandler", progressHandlerContext, &free_progress_handler); + set_new_handler(env, nativeDB, db_progressHandler, progressHandlerContext, &free_progress_handler); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_register_1progress_1handler( - JNIEnv* env, - jobject nativeDB, - jint vmCalls, - jobject progressHandler + JNIEnv *env, + jobject nativeDB, + jint vmCalls, + jobject progressHandler ) { - change_progress_handler(env, nativeDB, progressHandler, vmCalls); + change_progress_handler(env, nativeDB, progressHandler, vmCalls); } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_clear_1progress_1handler( - JNIEnv* env, - jobject nativeDB + JNIEnv *env, + jobject nativeDB ) { - change_progress_handler(env, nativeDB, NULL, 0); + change_progress_handler(env, nativeDB, NULL, 0); } // Update hook struct UpdateHandlerContext { - JavaVM* vm; - jobject handler; - jmethodID method; + JavaVM *vm; + jobject handler; }; -void update_hook(void* context, int type, char const* database, char const* table, sqlite3_int64 row) { - JNIEnv* env = 0; - struct UpdateHandlerContext* update_handler_context = (struct UpdateHandlerContext*)context; - (*update_handler_context->vm)->AttachCurrentThread(update_handler_context->vm, (void**)&env, 0); +void update_hook(void *context, int type, char const *database, char const *table, sqlite3_int64 row) { + JNIEnv *env = 0; + struct UpdateHandlerContext* update_handler_context = (struct UpdateHandlerContext*) context; + (*update_handler_context->vm)->AttachCurrentThread(update_handler_context->vm, (void **)&env, 0); - jstring databaseString = (*env)->NewStringUTF(env, database); - jstring tableString = (*env)->NewStringUTF(env, table); + jstring databaseString = (*env)->NewStringUTF(env, database); + jstring tableString = (*env)->NewStringUTF(env, table); - (*env)->CallVoidMethod(env, update_handler_context->handler, update_handler_context->method, type, databaseString, tableString, row); + (*env)->CallVoidMethod(env, update_handler_context->handler, db_mth_onUpdate, type, databaseString, tableString, row); - (*env)->DeleteLocalRef(env, databaseString); - (*env)->DeleteLocalRef(env, tableString); + (*env)->DeleteLocalRef(env, databaseString); + (*env)->DeleteLocalRef(env, tableString); } -static void free_update_handler(JNIEnv* env, void* ctx) { - struct UpdateHandlerContext* update_handler_context = (struct UpdateHandlerContext*)ctx; - (*env)->DeleteGlobalRef(env, update_handler_context->handler); - free(ctx); +static void free_update_handler(JNIEnv *env, void *ctx) { + struct UpdateHandlerContext* update_handler_context = (struct UpdateHandlerContext*) ctx; + (*env)->DeleteGlobalRef(env, update_handler_context->handler); + free(ctx); } -static void clear_update_listener(JNIEnv* env, jobject nativeDB) { - sqlite3_update_hook(gethandle(env, nativeDB), NULL, NULL); - set_new_handler(env, nativeDB, "updateListener", NULL, &free_update_handler); +static void clear_update_listener(JNIEnv *env, jobject nativeDB){ + sqlite3_update_hook(gethandle(env, nativeDB), NULL, NULL); + set_new_handler(env, nativeDB, db_updateListener, NULL, &free_update_handler); } -JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_set_1update_1listener(JNIEnv* env, jobject nativeDB, jboolean enabled) { - if (enabled) { - struct UpdateHandlerContext* update_handler_context = (struct UpdateHandlerContext*)malloc(sizeof(struct UpdateHandlerContext)); - update_handler_context->method = (*env)->GetMethodID(env, dbclass, "onUpdate", "(ILjava/lang/String;Ljava/lang/String;J)V"); - update_handler_context->handler = (*env)->NewGlobalRef(env, nativeDB); - (*env)->GetJavaVM(env, &update_handler_context->vm); - sqlite3_update_hook(gethandle(env, nativeDB), &update_hook, update_handler_context); - set_new_handler(env, nativeDB, "updateListener", update_handler_context, &free_update_handler); - } - else { - clear_update_listener(env, nativeDB); - } +JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_set_1update_1listener(JNIEnv *env, jobject nativeDB, jboolean enabled) { + if (enabled) { + struct UpdateHandlerContext* update_handler_context = (struct UpdateHandlerContext*) malloc(sizeof(struct UpdateHandlerContext)); + update_handler_context->handler = (*env)->NewGlobalRef(env, nativeDB); + (*env)->GetJavaVM(env, &update_handler_context->vm); + sqlite3_update_hook(gethandle(env, nativeDB), &update_hook, update_handler_context); + set_new_handler(env, nativeDB, db_updateListener, update_handler_context, &free_update_handler); + } else { + clear_update_listener(env, nativeDB); + } } // Commit hook struct CommitHandlerContext { - JavaVM* vm; - jobject handler; - jmethodID method; + JavaVM *vm; + jobject handler; }; -int commit_hook(void* context) { - struct CommitHandlerContext* commit_handler_context = (struct CommitHandlerContext*)context; - JNIEnv* env = 0; - (*commit_handler_context->vm)->AttachCurrentThread(commit_handler_context->vm, (void**)&env, 0); - (*env)->CallVoidMethod(env, commit_handler_context->handler, commit_handler_context->method, 1); - return 0; +int commit_hook(void *context) { + struct CommitHandlerContext *commit_handler_context = (struct CommitHandlerContext*) context; + JNIEnv *env = 0; + (*commit_handler_context->vm)->AttachCurrentThread(commit_handler_context->vm, (void **)&env, 0); + (*env)->CallVoidMethod(env, commit_handler_context->handler, db_mth_onCommit, 1); + return 0; } -void rollback_hook(void* context) { - struct CommitHandlerContext* commit_handler_context = (struct CommitHandlerContext*)context; - JNIEnv* env = 0; - (*commit_handler_context->vm)->AttachCurrentThread(commit_handler_context->vm, (void**)&env, 0); - (*env)->CallVoidMethod(env, commit_handler_context->handler, commit_handler_context->method, 0); +void rollback_hook(void *context) { + struct CommitHandlerContext *commit_handler_context = (struct CommitHandlerContext*) context; + JNIEnv *env = 0; + (*commit_handler_context->vm)->AttachCurrentThread(commit_handler_context->vm, (void **)&env, 0); + (*env)->CallVoidMethod(env, commit_handler_context->handler, db_mth_onCommit, 0); } -static void freeCommitHandlerCtx(JNIEnv* env, void* ctx) { - struct CommitHandlerContext* commit_handler_context = (struct CommitHandlerContext*)ctx; - (*env)->DeleteGlobalRef(env, commit_handler_context->handler); - free(ctx); +static void freeCommitHandlerCtx(JNIEnv *env, void *ctx) { + struct CommitHandlerContext* commit_handler_context = (struct CommitHandlerContext*) ctx; + (*env)->DeleteGlobalRef(env, commit_handler_context->handler); + free(ctx); } -void clear_commit_listener(JNIEnv* env, jobject nativeDB, sqlite3* db) { - sqlite3_commit_hook(db, NULL, NULL); - sqlite3_rollback_hook(db, NULL, NULL); - set_new_handler(env, nativeDB, "commitListener", NULL, freeCommitHandlerCtx); +void clear_commit_listener(JNIEnv *env, jobject nativeDB, sqlite3 *db) { + sqlite3_commit_hook(db, NULL, NULL); + sqlite3_rollback_hook(db, NULL, NULL); + set_new_handler(env, nativeDB, db_commitListener, NULL, freeCommitHandlerCtx); } -JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_set_1commit_1listener(JNIEnv* env, jobject nativeDB, jboolean enabled) { - sqlite3* db = gethandle(env, nativeDB); - if (enabled) { - struct CommitHandlerContext* commit_handler_context = (struct CommitHandlerContext*)malloc(sizeof(struct CommitHandlerContext)); - commit_handler_context->handler = (*env)->NewGlobalRef(env, nativeDB); - commit_handler_context->method = (*env)->GetMethodID(env, dbclass, "onCommit", "(Z)V"); - (*env)->GetJavaVM(env, &commit_handler_context->vm); - sqlite3_commit_hook(db, &commit_hook, commit_handler_context); - sqlite3_rollback_hook(db, &rollback_hook, commit_handler_context); - set_new_handler(env, nativeDB, "commitListener", commit_handler_context, freeCommitHandlerCtx); - } - else { - clear_commit_listener(env, nativeDB, db); - } +JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_set_1commit_1listener(JNIEnv *env, jobject nativeDB, jboolean enabled) { + sqlite3 *db = gethandle(env, nativeDB); + if (enabled) { + struct CommitHandlerContext *commit_handler_context = (struct CommitHandlerContext*) malloc(sizeof(struct CommitHandlerContext)); + commit_handler_context->handler = (*env)->NewGlobalRef(env, nativeDB); + (*env)->GetJavaVM(env, &commit_handler_context->vm); + sqlite3_commit_hook(db, &commit_hook, commit_handler_context); + sqlite3_rollback_hook(db, &rollback_hook, commit_handler_context); + set_new_handler(env, nativeDB, db_commitListener, commit_handler_context, freeCommitHandlerCtx); + } else { + clear_commit_listener(env, nativeDB, db); + } } JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB__1close( - JNIEnv* env, jobject nativeDB) -{ - sqlite3* db = gethandle(env, nativeDB); - if (db) - { - change_progress_handler(env, nativeDB, NULL, 0); - change_busy_handler(env, nativeDB, NULL); - clear_commit_listener(env, nativeDB, db); - clear_update_listener(env, nativeDB); - - if (sqlite3_close(db) != SQLITE_OK) - { - throwex(env, nativeDB); - } - sethandle(env, nativeDB, 0); - } + JNIEnv *env, jobject nativeDB) +{ + sqlite3 *db = gethandle(env, nativeDB); + if (db) + { + change_progress_handler(env, nativeDB, NULL, 0); + change_busy_handler(env, nativeDB, NULL); + clear_commit_listener(env, nativeDB, db); + clear_update_listener(env, nativeDB); + + if (sqlite3_close(db) != SQLITE_OK) + { + throwex(env, nativeDB); + } + sethandle(env, nativeDB, 0); + } +} + +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_core_NativeDB_serialize(JNIEnv *env, jobject this, jstring jschema) +{ + + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return NULL; + } + + const char* schema = (*env)->GetStringUTFChars(env, jschema, 0); + + sqlite3_int64 size; + int need_free=0; + unsigned char *buff = sqlite3_serialize(db, schema, &size, SQLITE_SERIALIZE_NOCOPY); + if (buff==NULL) + { + // This happens if we start without a deserialized database + buff = sqlite3_serialize(db, schema, &size, 0); + if (buff==NULL) + { + (*env)->ReleaseStringUTFChars(env, jschema, schema); + throwex_msg(env, "Serialization failed, allocation failed"); + return NULL; + } + need_free = 1; + } + (*env)->ReleaseStringUTFChars(env, jschema, schema); + + jbyteArray jbuff = (*env)->NewByteArray(env, size); + if (jbuff!=NULL) + { + void *jbuff_pointer = (*env)->GetPrimitiveArrayCritical(env, jbuff, NULL); + if (jbuff_pointer!=NULL) + { + memcpy(jbuff_pointer, buff, size); + (*env)->ReleasePrimitiveArrayCritical(env, jbuff, buff, 0); + } + else + { + throwex_msg(env, "Failed to get byte[] address"); + (*env)->DeleteLocalRef(env, jbuff); + jbuff = NULL; + } + } + else + { + throwex_msg(env, "Failed to allocate java byte[]"); + } + + + if (need_free) + { + sqlite3_free(buff); + } + return jbuff; +} + +JNIEXPORT void JNICALL Java_org_sqlite_core_NativeDB_deserialize(JNIEnv *env, jobject this, jstring jschema, jbyteArray jbuff) +{ + sqlite3 *db = gethandle(env, this); + if (!db) + { + throwex_db_closed(env); + return; + } + + jlong size = (*env)->GetArrayLength(env, jbuff); + unsigned char *sqlite_buff = sqlite3_malloc64(size); + if (sqlite_buff==NULL) + { + throwex_msg(env, "Failed to allocate native memory for database"); + return; + } + + void *buff = (*env)->GetPrimitiveArrayCritical(env, jbuff, NULL); + if (buff==NULL) + { + throwex_msg(env, "Failed to get byte[] address"); + sqlite3_free(sqlite_buff); + return; + } + memcpy(sqlite_buff, buff, size); + (*env)->ReleasePrimitiveArrayCritical(env, jbuff, buff, JNI_ABORT); + + const char* schema = (*env)->GetStringUTFChars(env, jschema, 0); + int ret = sqlite3_deserialize(db, schema, sqlite_buff, size, size, SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE); + if (ret!=SQLITE_OK) + { + throwex_errorcode(env, this, ret); + } + else + { + sqlite3_int64 max_size = 1024L * 1024L * 1000L * 2L; //~2gb, bigger values will result in sqlite malloc error + sqlite3_file_control(db, schema, SQLITE_FCNTL_SIZE_LIMIT, &max_size); + } + (*env)->ReleaseStringUTFChars(env, jschema, schema); } \ No newline at end of file diff --git a/C++/sqliteJDBC/sqliteJDBC/dllmain.cpp b/C++/sqliteJDBC/sqliteJDBC/dllmain.cpp index 1c601c9af..85a2edbe6 100644 --- a/C++/sqliteJDBC/sqliteJDBC/dllmain.cpp +++ b/C++/sqliteJDBC/sqliteJDBC/dllmain.cpp @@ -2,21 +2,21 @@ #include "pch.h" BOOL APIENTRY DllMain(HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved + DWORD ul_reason_for_call, + LPVOID lpReserved ) { - const auto dll_path = L".\\user\\"; - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - SetDllDirectory(dll_path); - break; - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - default: - break; - } - return TRUE; -} \ No newline at end of file + const auto dll_path = L".\\user\\"; + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + SetDllDirectory(dll_path); + break; + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + default: + break; + } + return TRUE; +} diff --git a/C++/sqliteJDBC/sqliteJDBC/sqlite3.h b/C++/sqliteJDBC/sqliteJDBC/sqlite3.h index b7c3e03b9..d4f1c810c 100644 --- a/C++/sqliteJDBC/sqliteJDBC/sqlite3.h +++ b/C++/sqliteJDBC/sqliteJDBC/sqlite3.h @@ -1,4 +1,4 @@ -/* +/* ** 2001-09-15 ** ** The author disclaims copyright to this source code. In place of @@ -43,7 +43,30 @@ extern "C" { /* -** Provide the ability to override linkage features of the interface. +** Facilitate override of interface linkage and calling conventions. +** Be aware that these macros may not be used within this particular +** translation of the amalgamation and its associated header file. +** +** The SQLITE_EXTERN and SQLITE_API macros are used to instruct the +** compiler that the target identifier should have external linkage. +** +** The SQLITE_CDECL macro is used to set the calling convention for +** public functions that accept a variable number of arguments. +** +** The SQLITE_APICALL macro is used to set the calling convention for +** public functions that accept a fixed number of arguments. +** +** The SQLITE_STDCALL macro is no longer used and is now deprecated. +** +** The SQLITE_CALLBACK macro is used to set the calling convention for +** function pointers. +** +** The SQLITE_SYSAPI macro is used to set the calling convention for +** functions provided by the operating system. +** +** Currently, the SQLITE_CDECL, SQLITE_APICALL, SQLITE_CALLBACK, and +** SQLITE_SYSAPI macros are used only when building for environments +** that require non-default calling conventions. */ #ifndef SQLITE_EXTERN # define SQLITE_EXTERN extern @@ -108,7 +131,7 @@ extern "C" { ** be held constant and Z will be incremented or else Y will be incremented ** and Z will be reset to zero. ** -** Since [version 3.6.18] ([dateof:3.6.18]), +** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the ** Fossil configuration management ** system. ^The SQLITE_SOURCE_ID macro evaluates to @@ -123,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.32.2" -#define SQLITE_VERSION_NUMBER 3032002 -#define SQLITE_SOURCE_ID "2020-06-04 12:58:43 ec02243ea6ce33b090870ae55ab8aa2534b54d216d45c4aa2fdbb00e86861e8c" +#define SQLITE_VERSION "3.44.0" +#define SQLITE_VERSION_NUMBER 3044000 +#define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -151,8 +174,8 @@ extern "C" { ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to -** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns -** a pointer to a string constant whose value is the same as the +** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built ** using an edited copy of [the amalgamation], then the last four characters ** of the hash might be different from [SQLITE_SOURCE_ID].)^ @@ -167,20 +190,20 @@ SQLITE_API int sqlite3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** -** ^The sqlite3_compileoption_used() function returns 0 or 1 -** indicating whether the specified option was defined at -** compile time. ^The SQLITE_ prefix may be omitted from the -** option name passed to sqlite3_compileoption_used(). +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). ** ** ^The sqlite3_compileoption_get() function allows iterating ** over the list of options that were defined at compile time by ** returning the N-th compile time option string. ^If N is out of range, -** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ -** prefix is omitted from any strings returned by +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by ** sqlite3_compileoption_get(). ** ** ^Support for the diagnostic functions sqlite3_compileoption_used() -** and sqlite3_compileoption_get() may be omitted by specifying the +** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and @@ -204,7 +227,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N); ** SQLite can be compiled with or without mutexes. When ** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes ** are enabled and SQLite is threadsafe. When the -** [SQLITE_THREADSAFE] macro is 0, +** [SQLITE_THREADSAFE] macro is 0, ** the mutexes are omitted. Without the mutexes, it is not safe ** to use SQLite concurrently from more than one thread. ** @@ -261,14 +284,14 @@ typedef struct sqlite3 sqlite3; ** ** ^The sqlite3_int64 and sqlite_int64 types can store integer values ** between -9223372036854775808 and +9223372036854775807 inclusive. ^The -** sqlite3_uint64 and sqlite_uint64 types can store integer values +** sqlite3_uint64 and sqlite_uint64 types can store integer values ** between 0 and +18446744073709551615 inclusive. */ #ifdef SQLITE_INT64_TYPE typedef SQLITE_INT64_TYPE sqlite_int64; # ifdef SQLITE_UINT64_TYPE typedef SQLITE_UINT64_TYPE sqlite_uint64; -# else +# else typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; # endif #elif defined(_MSC_VER) || defined(__BORLANDC__) @@ -300,7 +323,7 @@ typedef sqlite_uint64 sqlite3_uint64; ** resources are deallocated. ** ** Ideally, applications should [sqlite3_finalize | finalize] all -** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and +** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated ** with the [sqlite3] object prior to attempting to close the object. ** ^If the database connection is associated with unfinalized prepared @@ -344,7 +367,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL -** without having to use a lot of C code. +** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separate SQL statements passed into its 2nd argument, @@ -384,7 +407,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** from [sqlite3_column_name()]. ** ** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer -** to an empty string, or a pointer that contains only whitespace and/or +** to an empty string, or a pointer that contains only whitespace and/or ** SQL comments, then no SQL statements are evaluated and the database ** is not changed. ** @@ -504,6 +527,8 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) +#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) +#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -536,12 +561,14 @@ SQLITE_API int sqlite3_exec( #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) +#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) +#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ /* ** CAPI3REF: Flags For File Open Operations @@ -549,6 +576,19 @@ SQLITE_API int sqlite3_exec( ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +** +** Only those flags marked as "Ok for sqlite3_open_v2()" may be +** used as the third argument to the [sqlite3_open_v2()] interface. +** The other flags have historically been ignored by sqlite3_open_v2(), +** though future versions of SQLite might change so that an error is +** raised if any of the disallowed bits are passed into sqlite3_open_v2(). +** Applications should not depend on the historical behavior. +** +** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into +** [sqlite3_open_v2()] does *not* cause the underlying database file +** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into +** [sqlite3_open_v2()] has historically be a no-op and might become an +** error in future versions of SQLite. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ @@ -564,15 +604,19 @@ SQLITE_API int sqlite3_exec( #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ -#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_SUPER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */ /* Reserved: 0x00F00000 */ +/* Legacy compatibility: */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ + /* ** CAPI3REF: Device Characteristics @@ -628,13 +672,17 @@ SQLITE_API int sqlite3_exec( ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. +** of an [sqlite3_io_methods] object. These values are ordered from +** lest restrictive to most restrictive. +** +** The argument to xLock() is always SHARED or higher. The argument to +** xUnlock is either SHARED or NONE. */ -#define SQLITE_LOCK_NONE 0 -#define SQLITE_LOCK_SHARED 1 -#define SQLITE_LOCK_RESERVED 2 -#define SQLITE_LOCK_PENDING 3 -#define SQLITE_LOCK_EXCLUSIVE 4 +#define SQLITE_LOCK_NONE 0 /* xUnlock() only */ +#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ +#define SQLITE_LOCK_RESERVED 2 /* xLock() only */ +#define SQLITE_LOCK_PENDING 3 /* xLock() only */ +#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ /* ** CAPI3REF: Synchronization Type Flags @@ -669,7 +717,7 @@ SQLITE_API int sqlite3_exec( /* ** CAPI3REF: OS Interface Open File Handle ** -** An [sqlite3_file] object represents an open file in the +** An [sqlite3_file] object represents an open file in the ** [sqlite3_vfs | OS interface layer]. Individual OS interface ** implementations will ** want to subclass this object by appending additional fields @@ -691,7 +739,7 @@ struct sqlite3_file { ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** -** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element ** to a non-NULL pointer, then the sqlite3_io_methods.xClose method ** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The ** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] @@ -712,7 +760,14 @@ struct sqlite3_file { **
  • [SQLITE_LOCK_PENDING], or **
  • [SQLITE_LOCK_EXCLUSIVE]. ** -** xLock() increases the lock. xUnlock() decreases the lock. +** xLock() upgrades the database file lock. In other words, xLock() moves the +** database file lock in the direction NONE toward EXCLUSIVE. The argument to +** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never +** SQLITE_LOCK_NONE. If the database file lock is already at or above the +** requested lock, then the call to xLock() is a no-op. +** xUnlock() downgrades the database file lock to either SHARED or NONE. +* If the lock is already at or below the requested lock state, then the call +** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, ** PENDING, or EXCLUSIVE lock on the file. It returns true @@ -817,9 +872,8 @@ struct sqlite3_io_methods { ** opcode causes the xFileControl method to write the current state of ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. This capability -** is used during testing and is only available when the SQLITE_TEST -** compile-time option is used. +** into an integer that the pArg argument points to. +** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. ** **
  • [[SQLITE_FCNTL_SIZE_HINT]] ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS @@ -841,7 +895,7 @@ struct sqlite3_io_methods { **
  • [[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified -** by the user. The fourth argument to [sqlite3_file_control()] should +** by the user. The fourth argument to [sqlite3_file_control()] should ** point to an integer (type int) containing the new chunk-size to use ** for the nominated database. Allocating database file space in large ** chunks (say 1MB at a time), may reduce file-system fragmentation and @@ -864,24 +918,24 @@ struct sqlite3_io_methods { **
  • [[SQLITE_FCNTL_SYNC]] ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and ** sent to the VFS immediately before the xSync method is invoked on a -** database file descriptor. Or, if the xSync method is not invoked -** because the user has configured SQLite with -** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place +** database file descriptor. Or, if the xSync method is not invoked +** because the user has configured SQLite with +** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place ** of the xSync method. In most cases, the pointer argument passed with ** this file-control is NULL. However, if the database file is being synced ** as part of a multi-database commit, the argument points to a nul-terminated -** string containing the transactions master-journal file name. VFSes that -** do not need this signal should silently ignore this opcode. Applications -** should not call [sqlite3_file_control()] with this opcode as doing so may -** disrupt the operation of the specialized VFSes that do require it. +** string containing the transactions super-journal file name. VFSes that +** do not need this signal should silently ignore this opcode. Applications +** should not call [sqlite3_file_control()] with this opcode as doing so may +** disrupt the operation of the specialized VFSes that do require it. ** **
  • [[SQLITE_FCNTL_COMMIT_PHASETWO]] ** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite ** and sent to the VFS after a transaction has been committed immediately ** but before the database is unlocked. VFSes that do not need this signal ** should silently ignore this opcode. Applications should not call -** [sqlite3_file_control()] with this opcode as doing so may disrupt the -** operation of the specialized VFSes that do require it. +** [sqlite3_file_control()] with this opcode as doing so may disrupt the +** operation of the specialized VFSes that do require it. ** **
  • [[SQLITE_FCNTL_WIN32_AV_RETRY]] ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic @@ -929,13 +983,13 @@ struct sqlite3_io_methods { **
  • [[SQLITE_FCNTL_OVERWRITE]] ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some -** reason, the entire database file will be overwritten by the current +** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** **
  • [[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names are of all VFS shims and the -** final bottom-level VFS are written into memory obtained from +** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. ** The caller is responsible for freeing the memory when done. As with @@ -954,7 +1008,7 @@ struct sqlite3_io_methods { ** upper-most shim only. ** **
  • [[SQLITE_FCNTL_PRAGMA]] -** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding ** to the database file to which the pragma statement refers. ^The argument ** to the [SQLITE_FCNTL_PRAGMA] file control is an array of @@ -965,7 +1019,7 @@ struct sqlite3_io_methods { ** of the char** argument point to a string obtained from [sqlite3_mprintf()] ** or the equivalent and that string will become the result of the pragma or ** the error message if the pragma fails. ^If the -** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal ** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] ** file control returns [SQLITE_OK], then the parser assumes that the ** VFS has handled the PRAGMA itself and the parser generates a no-op @@ -1005,7 +1059,7 @@ struct sqlite3_io_methods { ** The argument is a pointer to a value of type sqlite3_int64 that ** is an advisory maximum number of bytes in the file to memory map. The ** pointer is overwritten with the old value. The limit is not changed if -** the value originally pointed to is negative, and so the current limit +** the value originally pointed to is negative, and so the current limit ** can be queried by passing in a pointer to a negative number. This ** file-control is used internally to implement [PRAGMA mmap_size]. ** @@ -1049,7 +1103,7 @@ struct sqlite3_io_methods { **
  • [[SQLITE_FCNTL_RBU]] ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by ** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for -** this opcode. +** this opcode. ** **
  • [[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]] ** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then @@ -1066,7 +1120,7 @@ struct sqlite3_io_methods { ** **
  • [[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]] ** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write -** operations since the previous successful call to +** operations since the previous successful call to ** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically. ** This file control returns [SQLITE_OK] if and only if the writes were ** all performed successfully and have been committed to persistent storage. @@ -1078,7 +1132,7 @@ struct sqlite3_io_methods { ** **
  • [[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]] ** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write -** operations since the previous successful call to +** operations since the previous successful call to ** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back. ** ^This file control takes the file descriptor out of batch write mode ** so that all subsequent write operations are independent. @@ -1087,8 +1141,8 @@ struct sqlite3_io_methods { ** **
  • [[SQLITE_FCNTL_LOCK_TIMEOUT]] ** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS -** to block for up to M milliseconds before failing when attempting to -** obtain a file lock using the xLock or xShmLock methods of the VFS. +** to block for up to M milliseconds before failing when attempting to +** obtain a file lock using the xLock or xShmLock methods of the VFS. ** The parameter is a pointer to a 32-bit signed integer that contains ** the value that M is to be set to. Before returning, the 32-bit signed ** integer is overwritten with the previous value of M. @@ -1123,6 +1177,28 @@ struct sqlite3_io_methods { ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. +** +**
  • [[SQLITE_FCNTL_EXTERNAL_READER]] +** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect +** whether or not there is a database client in another process with a wal-mode +** transaction open on the database or not. It is only available on unix.The +** (void*) argument passed with this file-control should be a pointer to a +** value of type (int). The integer value is set to 1 if the database is a wal +** mode database and there exists at least one client in another process that +** currently has an SQL transaction open on the database. It is set to 0 if +** the database is not a wal-mode db, or if there is no such connection in any +** other process. This opcode cannot be used to detect transactions opened +** by clients within the current process, only within other processes. +** +**
  • [[SQLITE_FCNTL_CKSM_FILE]] +** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the +** [checksum VFS shim] only. +** +**
  • [[SQLITE_FCNTL_RESET_CACHE]] +** If there is currently no transaction open on the database, and the +** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control +** purges the contents of the in-memory page cache. If there is an open +** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -1163,6 +1239,9 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 +#define SQLITE_FCNTL_EXTERNAL_READER 40 +#define SQLITE_FCNTL_CKSM_FILE 41 +#define SQLITE_FCNTL_RESET_CACHE 42 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -1192,6 +1271,26 @@ typedef struct sqlite3_mutex sqlite3_mutex; */ typedef struct sqlite3_api_routines sqlite3_api_routines; +/* +** CAPI3REF: File Name +** +** Type [sqlite3_filename] is used by SQLite to pass filenames to the +** xOpen method of a [VFS]. It may be cast to (const char*) and treated +** as a normal, nul-terminated, UTF-8 buffer containing the filename, but +** may also be passed to special APIs such as: +** +** +*/ +typedef const char *sqlite3_filename; + /* ** CAPI3REF: OS Interface Object ** @@ -1246,14 +1345,14 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter to xOpen is a NULL pointer then xOpen -** must invent its own temporary name for the file. ^Whenever the +** must invent its own temporary name for the file. ^Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** ** The flags argument to xOpen() includes all bits set in ** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] ** or [sqlite3_open16()] is used, then flags includes at least -** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. ** If xOpen() opens a file read-only then it sets *pOutFlags to ** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. ** @@ -1267,7 +1366,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; **
  • [SQLITE_OPEN_TEMP_JOURNAL] **
  • [SQLITE_OPEN_TRANSIENT_DB] **
  • [SQLITE_OPEN_SUBJOURNAL] -**
  • [SQLITE_OPEN_MASTER_JOURNAL] +**
  • [SQLITE_OPEN_SUPER_JOURNAL] **
  • [SQLITE_OPEN_WAL] ** )^ ** @@ -1295,10 +1394,10 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction ** with the [SQLITE_OPEN_CREATE] flag, which are both directly ** analogous to the O_EXCL and O_CREAT flags of the POSIX open() -** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the ** SQLITE_OPEN_CREATE, is used to indicate that file should always ** be created, and that it is an error if it already exists. -** It is not used to indicate the file should be opened +** It is not used to indicate the file should be opened ** for exclusive access. ** ** ^At least szOsFile bytes of memory are allocated by SQLite @@ -1322,7 +1421,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** non-zero error code if there is an I/O error or if the name of ** the file given in the second argument is illegal. If SQLITE_OK ** is returned, then non-zero or zero is written into *pResOut to indicate -** whether or not the file is accessible. +** whether or not the file is accessible. ** ** ^SQLite will always allocate at least mxPathname+1 bytes for the ** output buffer xFullPathname. The exact size of the output buffer @@ -1342,16 +1441,16 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** method returns a Julian Day Number for the current date and time as ** a floating point value. ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian -** Day Number multiplied by 86400000 (the number of milliseconds in -** a 24-hour day). +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). ** ^SQLite will use the xCurrentTimeInt64() method to get the current -** date and time if that method is available (if iVersion is 2 or +** date and time if that method is available (if iVersion is 2 or ** greater and the function pointer is not NULL) and will fall back ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. ** ** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces ** are not used by the SQLite core. These optional interfaces are provided -** by some VFSes to facilitate testing of the VFS code. By overriding +** by some VFSes to facilitate testing of the VFS code. By overriding ** system calls with functions under its control, a test program can ** simulate faults and error conditions that would otherwise be difficult ** or impossible to induce. The set of system calls that can be overridden @@ -1370,7 +1469,7 @@ struct sqlite3_vfs { sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); @@ -1398,7 +1497,7 @@ struct sqlite3_vfs { /* ** The methods above are in versions 1 through 3 of the sqlite_vfs object. ** New fields may be appended in future versions. The iVersion - ** value will increment whenever this happens. + ** value will increment whenever this happens. */ }; @@ -1442,7 +1541,7 @@ struct sqlite3_vfs { ** ** ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as -** was given on the corresponding lock. +** was given on the corresponding lock. ** ** The xShmLock method can transition between unlocked and SHARED or ** between unlocked and EXCLUSIVE. It cannot transition between SHARED @@ -1557,20 +1656,23 @@ SQLITE_API int sqlite3_os_end(void); ** must ensure that no other SQLite interfaces are invoked by other ** threads while sqlite3_config() is running. ** -** The sqlite3_config() interface -** may only be invoked prior to library initialization using -** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. -** ^If sqlite3_config() is called after [sqlite3_initialize()] and before -** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. -** Note, however, that ^sqlite3_config() can be called as part of the -** implementation of an application-defined [sqlite3_os_init()]. -** ** The first argument to sqlite3_config() is an integer ** [configuration option] that determines ** what property of SQLite is to be configured. Subsequent arguments ** vary depending on the [configuration option] ** in the first argument. ** +** For most configuration options, the sqlite3_config() interface +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** The exceptional configuration options that may be invoked at any time +** are called "anytime configuration options". +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] with a first argument that is not an anytime +** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. @@ -1587,7 +1689,7 @@ SQLITE_API int sqlite3_config(int, ...); ** [database connection] (specified in the first argument). ** ** The second argument to sqlite3_db_config(D,V,...) is the -** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** @@ -1605,7 +1707,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlite3_config()] when the configuration option is -** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. ** By creating an instance of this object ** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) ** during configuration, an application can specify an alternative @@ -1635,7 +1737,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. ** Every memory allocation request coming in through [sqlite3_malloc()] -** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. For example, @@ -1645,7 +1747,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); ** by xInit. The pAppData pointer is used as the only parameter to ** xInit and xShutdown. ** -** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** SQLite holds the [SQLITE_MUTEX_STATIC_MAIN] mutex when it invokes ** the xInit method, so the xInit method need not be threadsafe. The ** xShutdown method is only called from [sqlite3_shutdown()] so it does ** not need to be threadsafe either. For all other methods, SQLite @@ -1678,6 +1780,23 @@ struct sqlite3_mem_methods { ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** +** Most of the configuration options for sqlite3_config() +** will only work if invoked prior to [sqlite3_initialize()] or after +** [sqlite3_shutdown()]. The few exceptions to this rule are called +** "anytime configuration options". +** ^Calling [sqlite3_config()] with a first argument that is not an +** anytime configuration option in between calls to [sqlite3_initialize()] and +** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. +** +** The set of anytime configuration options can change (by insertions +** and/or deletions) from one release of SQLite to the next. +** As of SQLite version 3.42.0, the complete set of anytime configuration +** options is: +** +** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications ** should check the return code from [sqlite3_config()] to make sure that @@ -1693,7 +1812,7 @@ struct sqlite3_mem_methods { ** by a single thread. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** it is not possible to change the [threading mode] from its default -** value of Single-thread and so [sqlite3_config()] will return +** value of Single-thread and so [sqlite3_config()] will return ** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD ** configuration option. ** @@ -1728,7 +1847,7 @@ struct sqlite3_mem_methods { ** SQLITE_CONFIG_SERIALIZED configuration option. ** ** [[SQLITE_CONFIG_MALLOC]]
    SQLITE_CONFIG_MALLOC
    -**
    ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is +**
    ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is ** a pointer to an instance of the [sqlite3_mem_methods] structure. ** The argument specifies ** alternative low-level memory allocation routines to be used in place of @@ -1779,7 +1898,7 @@ struct sqlite3_mem_methods { ** [[SQLITE_CONFIG_PAGECACHE]]
    SQLITE_CONFIG_PAGECACHE
    **
    ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool ** that SQLite can use for the database page cache with the default page -** cache implementation. +** cache implementation. ** This configuration option is a no-op if an application-defined page ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]. ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to @@ -1807,7 +1926,7 @@ struct sqlite3_mem_methods { ** additional cache line.
    ** ** [[SQLITE_CONFIG_HEAP]]
    SQLITE_CONFIG_HEAP
    -**
    ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer +**
    ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer ** that SQLite will use for all of its dynamic memory allocation needs ** beyond those provided for by [SQLITE_CONFIG_PAGECACHE]. ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled @@ -1862,7 +1981,7 @@ struct sqlite3_mem_methods { ** configuration on individual connections.)^
    ** ** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    -**
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is +**
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is ** a pointer to an [sqlite3_pcache_methods2] object. This object specifies ** the interface to a custom page cache implementation.)^ ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.
    @@ -1876,7 +1995,7 @@ struct sqlite3_mem_methods { **
    The SQLITE_CONFIG_LOG option is used to configure the SQLite ** global [error log]. ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a -** function with a call signature of void(*)(void*,int,const char*), +** function with a call signature of void(*)(void*,int,const char*), ** and a pointer to void. ^If the function pointer is not NULL, it is ** invoked by [sqlite3_log()] to process each logging event. ^If the ** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. @@ -1985,7 +2104,7 @@ struct sqlite3_mem_methods { ** [[SQLITE_CONFIG_STMTJRNL_SPILL]] **
    SQLITE_CONFIG_STMTJRNL_SPILL **
    ^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which -** becomes the [statement journal] spill-to-disk threshold. +** becomes the [statement journal] spill-to-disk threshold. ** [Statement journals] are held in memory until their size (in bytes) ** exceeds this threshold, at which point they are written to disk. ** Or if the threshold is -1, statement journals are always held @@ -2007,8 +2126,8 @@ struct sqlite3_mem_methods { ** than the configured sorter-reference size threshold - then a reference ** is stored in each sorted record and the required column values loaded ** from the database as records are returned in sorted order. The default -** value for this option is to never use this optimization. Specifying a -** negative value for this option restores the default behaviour. +** value for this option is to never use this optimization. Specifying a +** negative value for this option restores the default behavior. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** @@ -2024,28 +2143,28 @@ struct sqlite3_mem_methods { ** compile-time option is not set, then the default maximum is 1073741824. ** */ -#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ -#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ -#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ -#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ -#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ -#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ -#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ -#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* no-op */ -#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ -#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ -#define SQLITE_CONFIG_URI 17 /* int */ -#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ -#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ @@ -2070,7 +2189,7 @@ struct sqlite3_mem_methods { **
    ** [[SQLITE_DBCONFIG_LOOKASIDE]] **
    SQLITE_DBCONFIG_LOOKASIDE
    -**
    ^This option takes three additional arguments that determine the +**
    ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** ^The first argument (the third parameter to [sqlite3_db_config()] is a ** pointer to a memory buffer to use for lookaside memory. @@ -2086,9 +2205,9 @@ struct sqlite3_mem_methods { ** configuration for a database connection can only be changed when that ** connection is not currently using lookaside memory, or in other words ** when the "current value" returned by -** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside -** memory is in use leaves the configuration unchanged and returns +** memory is in use leaves the configuration unchanged and returns ** [SQLITE_BUSY].)^
    ** ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] @@ -2111,7 +2230,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back.
    +** which case the trigger setting is not reported back. +** +**

    Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] **

    SQLITE_DBCONFIG_ENABLE_VIEW
    @@ -2122,7 +2247,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the view setting is not reported back. +** which case the view setting is not reported back. +** +**

    Originally this option disabled all views. ^(However, since +** SQLite version 3.35.0, TEMP views are still allowed even if +** this option is off. So, in other words, this option now only disables +** views in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **

    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
    @@ -2165,13 +2296,13 @@ struct sqlite3_mem_methods { ** until after the database connection closes. ** ** -** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] +** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] **
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    -**
    Usually, when a database in wal mode is closed or detached from a -** database handle, SQLite checks if this will mean that there are now no -** connections at all to the database. If so, it performs a checkpoint +**
    Usually, when a database in wal mode is closed or detached from a +** database handle, SQLite checks if this will mean that there are now no +** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to -** override this behaviour. The first parameter passed to this operation +** override this behavior. The first parameter passed to this operation ** is an integer - positive to disable checkpoints-on-close, or zero (the ** default) to enable them, and negative to leave the setting unchanged. ** The second parameter is a pointer to an integer @@ -2188,7 +2319,7 @@ struct sqlite3_mem_methods { ** slower. But the QPSG has the advantage of more predictable behavior. With ** the QPSG active, SQLite will always use the same query plan in the field as ** was used during testing in the lab. -** The first argument to this setting is an integer which is 0 to disable +** The first argument to this setting is an integer which is 0 to disable ** the QPSG, positive to enable QPSG, or negative to leave the setting ** unchanged. The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether the QPSG is disabled or enabled @@ -2196,15 +2327,15 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_TRIGGER_EQP]]
    SQLITE_DBCONFIG_TRIGGER_EQP
    -**
    By default, the output of EXPLAIN QUERY PLAN commands does not +**
    By default, the output of EXPLAIN QUERY PLAN commands does not ** include output for any operations performed by trigger programs. This ** option is used to set or clear (the default) a flag that governs this ** behavior. The first parameter passed to this operation is an integer - ** positive to enable output for trigger programs, or zero to disable it, ** or negative to leave the setting unchanged. -** The second parameter is a pointer to an integer into which is written -** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if -** it is not disabled, 1 if it is. +** The second parameter is a pointer to an integer into which is written +** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if +** it is not disabled, 1 if it is. **
    ** ** [[SQLITE_DBCONFIG_RESET_DATABASE]]
    SQLITE_DBCONFIG_RESET_DATABASE
    @@ -2218,24 +2349,29 @@ struct sqlite3_mem_methods { ** database, or calling sqlite3_table_column_metadata(), ignoring any ** errors. This step is only necessary if the application desires to keep ** the database in WAL mode after the reset if it was in WAL mode before -** the reset. +** the reset. **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
  • [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); ** ** Because resetting a database is destructive and irreversible, the -** process requires the use of this obscure API and multiple steps to help -** ensure that it does not happen by accident. +** process requires the use of this obscure API and multiple steps to +** help ensure that it does not happen by accident. Because this +** feature must be capable of resetting corrupt databases, and +** shutting down virtual tables may require access to that corrupt +** storage, the library must abandon any installed virtual tables +** without calling their xDestroy() methods. ** ** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    **
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the ** "defensive" flag for a database connection. When the defensive -** flag is enabled, language features that allow ordinary SQL to +** flag is enabled, language features that allow ordinary SQL to ** deliberately corrupt the database file are disabled. The disabled ** features include but are not limited to the following: ** @@ -2245,7 +2381,7 @@ struct sqlite3_mem_methods { **
    The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the ** "writable_schema" flag. This has the same effect and is logically equivalent ** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF]. -** The first argument to this setting is an integer which is 0 to disable +** The first argument to this setting is an integer which is 0 to disable ** the writable_schema, positive to enable writable_schema, or negative to ** leave the setting unchanged. The second parameter is a pointer to an ** integer into which is written 0 or 1 to indicate whether the writable_schema @@ -2263,7 +2399,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_DQS_DML]] -**
    SQLITE_DBCONFIG_DQS_DML +**
    SQLITE_DBCONFIG_DQS_DML
    **
    The SQLITE_DBCONFIG_DQS_DML option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DML statements ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The @@ -2272,7 +2408,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_DQS_DDL]] -**
    SQLITE_DBCONFIG_DQS_DDL +**
    SQLITE_DBCONFIG_DQS_DDL
    **
    The SQLITE_DBCONFIG_DQS option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DDL statements, ** such as CREATE TABLE and CREATE INDEX. The @@ -2281,16 +2417,15 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] -**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA +**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    **
    The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to -** assume that database schemas (the contents of the [sqlite_master] tables) -** are untainted by malicious content. +** assume that database schemas are untainted by malicious content. ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite ** takes additional defensive steps to protect the application from harm ** including: **
    ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] -**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT +**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    **
    The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly ** created database file to have a schema format version number (the 4-byte @@ -2311,7 +2446,7 @@ struct sqlite3_mem_methods { ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there -** is now scarcely any need to generated database files that are compatible +** is now scarcely any need to generate database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with version @@ -2320,8 +2455,40 @@ struct sqlite3_mem_methods { ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support -** either generated columns or decending indexes. +** either generated columns or descending indexes. +**
    +** +** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] +**
    SQLITE_DBCONFIG_STMT_SCANSTATUS
    +**
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in +** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears +** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() +** statistics. For statistics to be collected, the flag must be set on +** the database handle both when the SQL statement is prepared and when it +** is stepped. The flag is set (collection of statistics is enabled) +** by default. This option takes two arguments: an integer and a pointer to +** an integer.. The first argument is 1, 0, or -1 to enable, disable, or +** leave unchanged the statement scanstatus option. If the second argument +** is not NULL, then the value of the statement scanstatus setting after +** processing the first argument is written into the integer that the second +** argument points to. **
    +** +** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] +**
    SQLITE_DBCONFIG_REVERSE_SCANORDER
    +**
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order +** in which tables and indexes are scanned so that the scans start at the end +** and work toward the beginning rather than starting at the beginning and +** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the +** same as setting [PRAGMA reverse_unordered_selects]. This option takes +** two arguments which are an integer and a pointer to an integer. The first +** argument is 1, 0, or -1 to enable, disable, or leave unchanged the +** reverse scan order flag, respectively. If the second argument is not NULL, +** then 0 or 1 is written into the integer that the second argument points to +** depending on if the reverse scan order flag is set after processing the +** first argument. +**
    +** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -2342,7 +2509,9 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ +#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -2369,8 +2538,8 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of ** the most recent successful [INSERT] into a rowid table or [virtual table] ** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not -** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred -** on the database connection D, then sqlite3_last_insert_rowid(D) returns +** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred +** on the database connection D, then sqlite3_last_insert_rowid(D) returns ** zero. ** ** As well as being set automatically as rows are inserted into database @@ -2380,15 +2549,15 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); ** Some virtual table implementations may INSERT rows into rowid tables as ** part of committing a transaction (e.g. to flush data accumulated in memory ** to disk). In this case subsequent calls to this function return the rowid -** associated with these internal INSERT operations, which leads to +** associated with these internal INSERT operations, which leads to ** unintuitive results. Virtual table implementations that do write to rowid -** tables in this way can avoid this problem by restoring the original -** rowid value using [sqlite3_set_last_insert_rowid()] before returning +** tables in this way can avoid this problem by restoring the original +** rowid value using [sqlite3_set_last_insert_rowid()] before returning ** control to the user. ** -** ^(If an [INSERT] occurs within a trigger then this routine will -** return the [rowid] of the inserted row as long as the trigger is -** running. Once the trigger program ends, the value returned +** ^(If an [INSERT] occurs within a trigger then this routine will +** return the [rowid] of the inserted row as long as the trigger is +** running. Once the trigger program ends, the value returned ** by this routine reverts to what it was before the trigger was fired.)^ ** ** ^An [INSERT] that fails due to a constraint violation is not a @@ -2421,7 +2590,7 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** METHOD: sqlite3 ** ** The sqlite3_set_last_insert_rowid(D, R) method allows the application to -** set the value returned by calling sqlite3_last_insert_rowid(D) to R +** set the value returned by calling sqlite3_last_insert_rowid(D) to R ** without inserting a row into the database. */ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); @@ -2430,44 +2599,47 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 ** -** ^This function returns the number of rows modified, inserted or +** ^These functions return the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. -** ^Executing any other type of SQL statement does not modify the value -** returned by this function. +** The two functions are identical except for the type of the return value +** and that if the number of rows modified by the most recent INSERT, UPDATE +** or DELETE is greater than the maximum value supported by type "int", then +** the return value of sqlite3_changes() is undefined. ^Executing any other +** type of SQL statement does not modify the value returned by these functions. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are -** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], +** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], ** [foreign key actions] or [REPLACE] constraint resolution are not counted. -** -** Changes to a view that are intercepted by -** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value -** returned by sqlite3_changes() immediately after an INSERT, UPDATE or -** DELETE statement run on a view is always zero. Only changes made to real +** +** Changes to a view that are intercepted by +** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or +** DELETE statement run on a view is always zero. Only changes made to real ** tables are counted. ** ** Things are more complicated if the sqlite3_changes() function is ** executed while a trigger program is running. This may happen if the ** program uses the [changes() SQL function], or if some other callback ** function invokes sqlite3_changes() directly. Essentially: -** +** ** -** +** ** ^This means that if the changes() SQL function (or similar) is used -** by the first INSERT, UPDATE or DELETE statement within a trigger, it +** by the first INSERT, UPDATE or DELETE statement within a trigger, it ** returns the value as set when the calling statement began executing. -** ^If it is used by the second or subsequent such statement within a trigger -** program, the value returned reflects the number of rows modified by the +** ^If it is used by the second or subsequent such statement within a trigger +** program, the value returned reflects the number of rows modified by the ** previous INSERT, UPDATE or DELETE statement within the same trigger. ** ** If a separate thread makes changes on the same database connection @@ -2483,20 +2655,25 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** */ SQLITE_API int sqlite3_changes(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified ** METHOD: sqlite3 ** -** ^This function returns the total number of rows inserted, modified or +** ^These functions return the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as -** part of trigger programs. ^Executing any other type of SQL statement -** does not affect the value returned by sqlite3_total_changes(). -** +** part of trigger programs. The two functions are identical except for the +** type of the return value and that if the number of rows modified by the +** connection exceeds the maximum value supported by type "int", then +** the return value of sqlite3_total_changes() is undefined. ^Executing +** any other type of SQL statement does not affect the value returned by +** sqlite3_total_changes(). +** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are -** not. ^Changes to a view that are intercepted by INSTEAD OF triggers +** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. ** ** The [sqlite3_total_changes(D)] interface only reports the number @@ -2505,7 +2682,7 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** To detect changes against a database file from other database ** connections use the [PRAGMA data_version] command or the ** [SQLITE_FCNTL_DATA_VERSION] [file control]. -** +** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. @@ -2520,6 +2697,7 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** */ SQLITE_API int sqlite3_total_changes(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query @@ -2547,7 +2725,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** ** ^The sqlite3_interrupt(D) call is in effect until all currently running ** SQL statements on [database connection] D complete. ^Any new SQL statements -** that are started after the sqlite3_interrupt() call and before the +** that are started after the sqlite3_interrupt() call and before the ** running statement count reaches zero are interrupted as if they had been ** running prior to the sqlite3_interrupt() call. ^New SQL statements ** that are started after the running statement count reaches zero are @@ -2555,8 +2733,13 @@ SQLITE_API int sqlite3_total_changes(sqlite3*); ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. +** +** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether +** or not an interrupt is currently in effect for [database connection] D. +** It returns 1 if an interrupt is currently in effect, or 0 otherwise. */ SQLITE_API void sqlite3_interrupt(sqlite3*); +SQLITE_API int sqlite3_is_interrupted(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete @@ -2579,7 +2762,7 @@ SQLITE_API void sqlite3_interrupt(sqlite3*); ** ^These routines do not parse the SQL statements thus ** will not detect syntactically incorrect SQL. ** -** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked ** automatically by sqlite3_complete16(). If that initialization fails, ** then the return value from sqlite3_complete16() will be non-zero @@ -2624,7 +2807,7 @@ SQLITE_API int sqlite3_complete16(const void *sql); ** The presence of a busy handler does not guarantee that it will be invoked ** when there is lock contention. ^If SQLite determines that invoking the busy ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] -** to the application instead of invoking the +** to the application instead of invoking the ** busy handler. ** Consider a scenario where one process is holding a read lock that ** it is trying to promote to a reserved lock and @@ -2649,7 +2832,7 @@ SQLITE_API int sqlite3_complete16(const void *sql); ** database connection that invoked the busy handler. In other words, ** the busy handler is not reentrant. Any such actions ** result in undefined behavior. -** +** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ @@ -2767,7 +2950,7 @@ SQLITE_API void sqlite3_free_table(char **result); ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** These routines understand most of the common formatting options from -** the standard library printf() +** the standard library printf() ** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). ** See the [built-in printf()] documentation for details. ** @@ -2963,7 +3146,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** requested is ok. ^When the callback returns [SQLITE_DENY], the ** [sqlite3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that -** access is denied. +** access is denied. ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter @@ -3016,7 +3199,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** database connections for the meaning of "modify" in this paragraph. ** ** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be re-prepared during [sqlite3_step()] due to a +** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** @@ -3164,7 +3347,7 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** execution of the prepared statement, such as at the start of each ** trigger subprogram. ^The P argument is a pointer to the ** [prepared statement]. ^The X argument is a pointer to a string which -** is the unexpanded SQL text of the prepared statement or an SQL comment +** is the unexpanded SQL text of the prepared statement or an SQL comment ** that indicates the invocation of a trigger. ^The callback can compute ** the same text that would have been returned by the legacy [sqlite3_trace()] ** interface by using the X argument when X begins with "--" and invoking @@ -3174,13 +3357,13 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, **
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is the estimated of -** the number of nanosecond that the prepared statement took to run. +** X argument points to a 64-bit integer which is approximately +** the number of nanoseconds that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    **
    ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared -** statement generates a single row of result. +** statement generates a single row of result. ** ^The P argument is a pointer to the [prepared statement] and the ** X argument is unused. ** @@ -3207,10 +3390,12 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** M argument should be the bitwise OR-ed combination of ** zero or more [SQLITE_TRACE] constants. ** -** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides -** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). +** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P) +** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or +** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each +** database connection may have at most one trace callback. ** -** ^The X callback is invoked whenever any of the events identified by +** ^The X callback is invoked whenever any of the events identified by ** mask M occur. ^The integer return value from the callback is currently ** ignored, though this may change in future releases. Callback ** implementations should return zero to ensure future compatibility. @@ -3238,12 +3423,12 @@ SQLITE_API int sqlite3_trace_v2( ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to -** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** [sqlite3_step()] and [sqlite3_prepare()] and similar for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** -** ^The parameter P is passed through as the only parameter to the -** callback function X. ^The parameter N is the approximate number of +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive ** invocations of the callback X. ^If N is less than one then the progress ** handler is disabled. @@ -3263,6 +3448,13 @@ SQLITE_API int sqlite3_trace_v2( ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** +** The progress handler callback would originally only be invoked from the +** bytecode engine. It still might be invoked during [sqlite3_prepare()] +** and similar because those routines might force a reparse of the schema +** which involves running the bytecode engine. However, beginning with +** SQLite version 3.41.0, the progress handler callback might also be +** invoked directly from [sqlite3_prepare()] while analyzing and generating +** code for complex queries. */ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); @@ -3270,7 +3462,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** CAPI3REF: Opening A New Database Connection ** CONSTRUCTOR: sqlite3 ** -** ^These routines open an SQLite database file as specified by the +** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for ** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte ** order for sqlite3_open16(). ^(A [database connection] handle is usually @@ -3299,13 +3491,18 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** **
    ** ^(
    [SQLITE_OPEN_READONLY]
    -**
    The database is opened in read-only mode. If the database does not -** already exist, an error is returned.
    )^ +**
    The database is opened in read-only mode. If the database does +** not already exist, an error is returned.
    )^ ** ** ^(
    [SQLITE_OPEN_READWRITE]
    -**
    The database is opened for reading and writing if possible, or reading -** only if the file is write protected by the operating system. In either -** case the database must already exist, otherwise an error is returned.
    )^ +**
    The database is opened for reading and writing if possible, or +** reading only if the file is write protected by the operating +** system. In either case the database must already exist, otherwise +** an error is returned. For historical reasons, if opening in +** read-write mode fails due to OS-level permissions, an attempt is +** made to open it in read-only mode. [sqlite3_db_readonly()] can be +** used to determine whether the database is actually +** read-write.
    )^ ** ** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    **
    The database is opened for reading and writing, and is created if @@ -3343,20 +3540,39 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); **
    The database is opened [shared cache] enabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ +** The [use of shared cache mode is discouraged] and hence shared cache +** capabilities may be omitted from many builds of SQLite. In such cases, +** this option is a no-op. ** ** ^(
    [SQLITE_OPEN_PRIVATECACHE]
    **
    The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** +** [[OPEN_EXRESCODE]] ^(
    [SQLITE_OPEN_EXRESCODE]
    +**
    The database connection comes up in "extended result code mode". +** In other words, the database behaves has if +** [sqlite3_extended_result_codes(db,1)] where called on the database +** connection as soon as the connection is created. In addition to setting +** the extended result code mode, this flag also causes [sqlite3_open_v2()] +** to return an extended result code.
    +** ** [[OPEN_NOFOLLOW]] ^(
    [SQLITE_OPEN_NOFOLLOW]
    -**
    The database filename is not allowed to be a symbolic link
    +**
    The database filename is not allowed to contain a symbolic link
    **
    )^ ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] -** then the behavior is undefined. +** then the behavior is undefined. Historic versions of SQLite +** have silently ignored surplus bits in the flags parameter to +** sqlite3_open_v2(), however that behavior might not be carried through +** into future versions of SQLite and so applications should not rely +** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op +** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause +** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE +** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not +** by sqlite3_open_v2(). ** ** ^The fourth parameter to sqlite3_open_v2() is the name of the ** [sqlite3_vfs] object that defines the operating system interface that @@ -3389,17 +3605,17 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** information. ** ** URI filenames are parsed according to RFC 3986. ^If the URI contains an -** authority, then it must be either an empty string or the string -** "localhost". ^If the authority is not an empty string or "localhost", an -** error is returned to the caller. ^The fragment component of a URI, if +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if ** present, is ignored. ** ** ^SQLite uses the path component of the URI as the name of the disk file -** which contains the database. ^If the path begins with a '/' character, -** then it is interpreted as an absolute path. ^If the path does not begin +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin ** with a '/' (meaning that the authority section is omitted from the URI) -** then the path is interpreted as a relative path. -** ^(On windows, the first component of an absolute path +** then the path is interpreted as a relative path. +** ^(On windows, the first component of an absolute path ** is a drive specification (e.g. "C:").)^ ** ** [[core URI query parameters]] @@ -3419,13 +3635,13 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** **
  • mode: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is -** an error)^. -** ^If "ro" is specified, then the database is opened for read-only -** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the -** third argument to sqlite3_open_v2(). ^If the mode option is set to -** "rw", then the database is opened for read-write (but not create) -** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had -** been set. ^Value "rwc" is equivalent to setting both +** an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_open_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for @@ -3435,7 +3651,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); **
  • cache: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to -** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behavior requested by setting @@ -3461,7 +3677,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** property on a database file that does in fact change can result ** in incorrect query results and/or [SQLITE_CORRUPT] errors. ** See also: [SQLITE_IOCAP_IMMUTABLE]. -** +** ** ** ** ^Specifying an unknown parameter in the query component of a URI is not an @@ -3473,36 +3689,37 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** **
    URI filenames Results -**
    file:data.db +**
    file:data.db ** Open the file "data.db" in the current directory. **
    file:/home/fred/data.db
    -** file:///home/fred/data.db
    -** file://localhost/home/fred/data.db
    +** file:///home/fred/data.db
    +** file://localhost/home/fred/data.db
    ** Open the database file "/home/fred/data.db". -**
    file://darkstar/home/fred/data.db +**
    file://darkstar/home/fred/data.db ** An error. "darkstar" is not a recognized authority. -**
    +**
    ** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db ** Windows only: Open the file "data.db" on fred's desktop on drive -** C:. Note that the %20 escaping in this example is not strictly +** C:. Note that the %20 escaping in this example is not strictly ** necessary - space characters can be used literally ** in URI filenames. -**
    file:data.db?mode=ro&cache=private +**
    file:data.db?mode=ro&cache=private ** Open file "data.db" in the current directory for read-only access. ** Regardless of whether or not shared-cache mode is enabled by ** default, use a private cache. **
    file:/home/fred/data.db?vfs=unix-dotfile ** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" ** that uses dot-files in place of posix advisory locking. -**
    file:data.db?mode=readonly +**
    file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". **
    ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and ** query components of a URI. A hexadecimal escape sequence consists of a -** percent sign - "%" - followed by exactly two hexadecimal digits +** percent sign - "%" - followed by exactly two hexadecimal digits ** specifying an octet value. ^Before the path or query components of a -** URI filename are interpreted, they are encoded using UTF-8 and all +** URI filename are interpreted, they are encoded using UTF-8 and all ** hexadecimal escape sequences replaced by a single byte containing the ** corresponding octet. If this process generates an invalid UTF-8 encoding, ** the results are undefined. @@ -3538,14 +3755,14 @@ SQLITE_API int sqlite3_open_v2( ** CAPI3REF: Obtain Values For URI Parameters ** ** These are utility routines, useful to [VFS|custom VFS implementations], -** that check if a database file was a URI that contained a specific query +** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** ** The first parameter to these interfaces (hereafter referred to ** as F) must be one of: **
      **
    • A database filename pointer created by the SQLite core and -** passed into the xOpen() method of a VFS implemention, or +** passed into the xOpen() method of a VFS implementation, or **
    • A filename obtained from [sqlite3_db_filename()], or **
    • A new filename constructed using [sqlite3_create_filename()]. **
    @@ -3556,7 +3773,7 @@ SQLITE_API int sqlite3_open_v2( ** If F is a suitable filename (as described in the previous paragraph) ** and if P is the name of the query parameter, then ** sqlite3_uri_parameter(F,P) returns the value of the P -** parameter if it exists or a NULL pointer if P does not appear as a +** parameter if it exists or a NULL pointer if P does not appear as a ** query parameter on F. If P is a query parameter of F and it ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. @@ -3565,7 +3782,7 @@ SQLITE_API int sqlite3_open_v2( ** parameter and returns true (1) or false (0) according to the value ** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the ** value of query parameter P is one of "yes", "true", or "on" in any -** case or if the value begins with a non-zero number. The +** case or if the value begins with a non-zero number. The ** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of ** query parameter P is one of "no", "false", or "off" in any case or ** if the value begins with a numeric zero. If P is not a query @@ -3583,7 +3800,7 @@ SQLITE_API int sqlite3_open_v2( ** parameters minus 1. The N value is zero-based so N should be 0 to obtain ** the name of the first query parameter, 1 for the second parameter, and ** so forth. -** +** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that the SQLite core passed @@ -3600,10 +3817,10 @@ SQLITE_API int sqlite3_open_v2( ** ** See the [URI filename] documentation for additional information. */ -SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); -SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); +SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); /* ** CAPI3REF: Translate filenames @@ -3632,22 +3849,22 @@ SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ -SQLITE_API const char *sqlite3_filename_database(const char*); -SQLITE_API const char *sqlite3_filename_journal(const char*); -SQLITE_API const char *sqlite3_filename_wal(const char*); +SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is -** passed into the xOpen method of [sqlite3_vfs], then +** passed into the xOpen method of [sqlite3_vfs], then ** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file] ** object that represents the main database file. ** ** This routine is intended for use in custom [VFS] implementations ** only. It is not a general-purpose interface. ** The argument sqlite3_file_object(X) must be a filename pointer that -** has been passed into [sqlite3_vfs].xOpen method where the +** has been passed into [sqlite3_vfs].xOpen method where the ** flags parameter to xOpen contains one of the bits ** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use ** of this routine results in undefined and probably undesirable @@ -3658,7 +3875,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** -** These interfces are provided for use by [VFS shim] implementations and +** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of @@ -3670,7 +3887,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); **
  • [sqlite3_uri_parameter()], **
  • [sqlite3_uri_boolean()], **
  • [sqlite3_uri_int64()], -**
  • [sqlite3_uri_key()], +**
  • [sqlite3_uri_key()], **
  • [sqlite3_filename_database()], **
  • [sqlite3_filename_journal()], or **
  • [sqlite3_filename_wal()]. @@ -3694,31 +3911,31 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap -** corruption or segfaults may occur. The value Y should be +** corruption or segfaults may occur. The value Y should not be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be ** invoked prior to calling sqlite3_free_filename(Y). */ -SQLITE_API char *sqlite3_create_filename( +SQLITE_API sqlite3_filename sqlite3_create_filename( const char *zDatabase, const char *zJournal, const char *zWal, int nParam, const char **azParam ); -SQLITE_API void sqlite3_free_filename(char*); +SQLITE_API void sqlite3_free_filename(sqlite3_filename); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** -** ^If the most recent sqlite3_* API call associated with +** ^If the most recent sqlite3_* API call associated with ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. ** ^The sqlite3_extended_errcode() -** interface is the same except that it always returns the +** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** @@ -3726,17 +3943,19 @@ SQLITE_API void sqlite3_free_filename(char*); ** sqlite3_extended_errcode() might change with each API call. ** Except, there are some interfaces that are guaranteed to never ** change the value of the error code. The error-code preserving -** interfaces are: +** interfaces include the following: ** **
      **
    • sqlite3_errcode() **
    • sqlite3_extended_errcode() **
    • sqlite3_errmsg() **
    • sqlite3_errmsg16() +**
    • sqlite3_error_offset() **
    ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. +** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by @@ -3747,6 +3966,13 @@ SQLITE_API void sqlite3_free_filename(char*); ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** +** ^If the most recent error references a specific token in the input +** SQL, the sqlite3_error_offset() interface returns the byte offset +** of the start of that token. ^The byte offset returned by +** sqlite3_error_offset() assumes that the input SQL is UTF8. +** ^If the most recent error does not reference a specific token in the input +** SQL, then the sqlite3_error_offset() function returns -1. +** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. @@ -3766,6 +3992,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Prepared Statement Object @@ -3775,7 +4002,7 @@ SQLITE_API const char *sqlite3_errstr(int); ** has been compiled into binary form and is ready to be evaluated. ** ** Think of each SQL statement as a separate computer program. The -** original SQL text is source code. A prepared statement object +** original SQL text is source code. A prepared statement object ** is the compiled object code. All SQL must be converted into a ** prepared statement before it can be run. ** @@ -3805,7 +4032,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** new limit for that construct.)^ ** ** ^If the new limit is a negative number, the limit is unchanged. -** ^(For each limit category SQLITE_LIMIT_NAME there is a +** ^(For each limit category SQLITE_LIMIT_NAME there is a ** [limits | hard upper bound] ** set at compile-time by a C preprocessor macro called ** [limits | SQLITE_MAX_NAME]. @@ -3813,7 +4040,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** ^Attempts to increase a limit above its hard upper bound are ** silently truncated to the hard upper bound. ** -** ^Regardless of whether or not the limit was changed, the +** ^Regardless of whether or not the limit was changed, the ** [sqlite3_limit()] interface returns the prior value of the limit. ** ^Hence, to find the current value of a limit without changing it, ** simply invoke this interface with the third parameter set to -1. @@ -3918,7 +4145,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); **
    The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner ** that the prepared statement will be retained for a long time and ** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()] -** and [sqlite3_prepare16_v3()] assume that the prepared statement will +** and [sqlite3_prepare16_v3()] assume that the prepared statement will ** be used just once or at most a few times and then destroyed using ** [sqlite3_finalize()] relatively soon. The current implementation acts ** on this hint by avoiding the use of [lookaside memory] so as not to @@ -4025,12 +4252,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); **
  • ** **
  • -** ^If the specific value bound to a [parameter | host parameter] in the +** ^If the specific value bound to a [parameter | host parameter] in the ** WHERE clause might influence the choice of query plan for a statement, -** then the statement will be automatically recompiled, as if there had been +** then the statement will be automatically recompiled, as if there had been ** a schema change, on the first [sqlite3_step()] call following any change -** to the [sqlite3_bind_text | bindings] of that [parameter]. -** ^The specific value of a WHERE-clause [parameter] might influence the +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of a WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled. @@ -4123,12 +4350,17 @@ SQLITE_API int sqlite3_prepare16_v3( ** are managed by SQLite and are automatically freed when the prepared ** statement is finalized. ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, -** is obtained from [sqlite3_malloc()] and must be free by the application +** is obtained from [sqlite3_malloc()] and must be freed by the application ** by passing it to [sqlite3_free()]. +** +** ^The sqlite3_normalized_sql() interface is only available if +** the [SQLITE_ENABLE_NORMALIZE] compile-time option is defined. */ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +#ifdef SQLITE_ENABLE_NORMALIZE SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); +#endif /* ** CAPI3REF: Determine If An SQL Statement Writes The Database @@ -4139,8 +4371,8 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** the content of the database file. ** ** Note that [application-defined SQL functions] or -** [virtual tables] might change the database indirectly as a side effect. -** ^(For example, if an application defines a function "eval()" that +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that ** calls [sqlite3_exec()], then the following SQL statement would ** change the database file through side-effects: ** @@ -4154,15 +4386,28 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], ** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, ** since the statements themselves do not actually modify the database but -** rather they control the timing of when other statements modify the +** rather they control the timing of when other statements modify the ** database. ^The [ATTACH] and [DETACH] statements also cause ** sqlite3_stmt_readonly() to return true since, while those statements -** change the configuration of a database connection, they do not make +** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. ** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since ** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and ** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so ** sqlite3_stmt_readonly() returns false for those commands. +** +** ^This routine returns false if there is any possibility that the +** statement might change the database file. ^A false return does +** not guarantee that the statement will change the database file. +** ^For example, an UPDATE statement might have a WHERE clause that +** makes it a no-op, but the sqlite3_stmt_readonly() result would still +** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a +** read-only no-op if the table already exists, but +** sqlite3_stmt_readonly() still returns false for such a statement. +** +** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] +** statement, then sqlite3_stmt_readonly(X) returns the same value as +** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -4178,23 +4423,58 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); +/* +** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement +** METHOD: sqlite3_stmt +** +** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN +** setting for [prepared statement] S. If E is zero, then S becomes +** a normal prepared statement. If E is 1, then S behaves as if +** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if +** its SQL text began with "[EXPLAIN QUERY PLAN]". +** +** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. +** SQLite tries to avoid a reprepare, but a reprepare might be necessary +** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode. +** +** Because of the potential need to reprepare, a call to +** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be +** reprepared because it was created using [sqlite3_prepare()] instead of +** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and +** hence has no saved SQL text with which to reprepare. +** +** Changing the explain setting for a prepared statement does not change +** the original SQL text for the statement. Hence, if the SQL text originally +** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0) +** is called to convert the statement into an ordinary statement, the EXPLAIN +** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S) +** output, even though the statement now acts like a normal SQL statement. +** +** This routine returns SQLITE_OK if the explain mode is successfully +** changed, or an error code if the explain mode could not be changed. +** The explain mode cannot be changed while a statement is active. +** Hence, it is good practice to call [sqlite3_reset(S)] +** immediately prior to calling sqlite3_stmt_explain(S,E). +*/ +SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); + /* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset ** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the -** [prepared statement] S has been stepped at least once using +** [prepared statement] S has been stepped at least once using ** [sqlite3_step(S)] but has neither run to completion (returned ** [SQLITE_DONE] from [sqlite3_step(S)]) nor ** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) -** interface returns false if S is a NULL pointer. If S is not a +** interface returns false if S is a NULL pointer. If S is not a ** NULL pointer and is not a pointer to a valid [prepared statement] ** object, then the behavior is undefined and probably undesirable. ** ** This interface can be used in combination [sqlite3_next_stmt()] -** to locate all prepared statements associated with a database +** to locate all prepared statements associated with a database ** connection that are in need of being reset. This can be used, -** for example, in diagnostic routines to search for prepared +** for example, in diagnostic routines to search for prepared ** statements that are holding a transaction open. */ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); @@ -4213,7 +4493,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** will accept either a protected or an unprotected sqlite3_value. ** Every interface that accepts sqlite3_value arguments specifies ** whether or not it requires a protected sqlite3_value. The -** [sqlite3_value_dup()] interface can be used to construct a new +** [sqlite3_value_dup()] interface can be used to construct a new ** protected sqlite3_value from an unprotected sqlite3_value. ** ** The terms "protected" and "unprotected" refer to whether or not @@ -4221,7 +4501,7 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** sqlite3_value object but no mutex is held for an unprotected ** sqlite3_value object. If SQLite is compiled to be single-threaded ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) -** or if SQLite is run in one of reduced mutex modes +** or if SQLite is run in one of reduced mutex modes ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] ** then there is no distinction between protected and unprotected ** sqlite3_value objects and they can be used interchangeably. However, @@ -4231,6 +4511,8 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** ** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()] +** are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. ** Unprotected sqlite3_value objects may only be used as arguments @@ -4310,7 +4592,7 @@ typedef struct sqlite3_context sqlite3_context; ** found in first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in -** the 6th parameter for sqlite3_bind_text64().)^ +** the 6th parameter for sqlite3_bind_text64().)^ ** ^If UTF16 input text contains invalid unicode ** characters, then SQLite might change those invalid characters ** into the unicode replacement character: U+FFFD. @@ -4327,23 +4609,27 @@ typedef struct sqlite3_context sqlite3_context; ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occurs at byte offsets less than +** terminated. If any NUL characters occurs at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** -** ^The fifth argument to the BLOB and string binding interfaces -** is a destructor used to dispose of the BLOB or -** string after SQLite has finished with it. ^The destructor is called -** to dispose of the BLOB or string even if the call to the bind API fails, -** except the destructor is not called if the third parameter is a NULL -** pointer or the fourth parameter is negative. -** ^If the fifth argument is -** the special value [SQLITE_STATIC], then SQLite assumes that the -** information is in static, unmanaged space and does not need to be freed. -** ^If the fifth argument has the value [SQLITE_TRANSIENT], then -** SQLite makes its own private copy of the data immediately, before -** the sqlite3_bind_*() routine returns. +** ^The fifth argument to the BLOB and string binding interfaces controls +** or indicates the lifetime of the object referenced by the third parameter. +** These three options exist: +** ^ (1) A destructor to dispose of the BLOB or string after SQLite has finished +** with it may be passed. ^It is called to dispose of the BLOB or string even +** if the call to the bind API fails, except the destructor is not called if +** the third parameter is a NULL pointer or the fourth parameter is negative. +** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that +** the application remains responsible for disposing of the object. ^In this +** case, the object and the provided pointer to it must remain valid until +** either the prepared statement is finalized or the same SQL parameter is +** bound to something else, whichever occurs sooner. +** ^ (3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the +** object is to be copied prior to the return from sqlite3_bind_*(). ^The +** object and pointer to it must remain valid until then. ^SQLite will then +** manage the lifetime of its private copy. ** ** ^The sixth argument to sqlite3_bind_text64() must be one of ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] @@ -4489,7 +4775,7 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the -** [prepared statement]. ^If this routine returns 0, that means the +** [prepared statement]. ^If this routine returns 0, that means the ** [prepared statement] returns no data (for example an [UPDATE]). ** ^However, just because this routine returns a positive number does not ** mean that one or more rows of data will be returned. ^A SELECT statement @@ -4671,7 +4957,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** For all versions of SQLite up to and including 3.6.23.1, a call to ** [sqlite3_reset()] was required after sqlite3_step() returned anything ** other than [SQLITE_ROW] before any subsequent invocation of -** sqlite3_step(). Failure to reset the prepared statement using +** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from ** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], ** sqlite3_step() began @@ -4762,7 +5048,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** sqlite3_column_int64→64-bit INTEGER result ** sqlite3_column_text→UTF-8 TEXT result ** sqlite3_column_text16→UTF-16 TEXT result -** sqlite3_column_value→The result as an +** sqlite3_column_value→The result as an ** [sqlite3_value|unprotected sqlite3_value] object. **     ** sqlite3_column_bytes→Size of a BLOB @@ -4810,7 +5096,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** The return value of sqlite3_column_type() can be used to decide which ** of the first six interface should be used to extract the column value. ** The value returned by sqlite3_column_type() is only meaningful if no -** automatic type conversions have occurred for the value in question. +** automatic type conversions have occurred for the value in question. ** After a type conversion, the result of calling sqlite3_column_type() ** is undefined, though harmless. Future ** versions of SQLite may change the behavior of sqlite3_column_type() @@ -4838,7 +5124,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** the number of bytes in that string. ** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. ** -** ^The values returned by [sqlite3_column_bytes()] and +** ^The values returned by [sqlite3_column_bytes()] and ** [sqlite3_column_bytes16()] do not include the zero terminators at the end ** of the string. ^For clarity: the values returned by ** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of @@ -4848,6 +5134,10 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** +** ^Strings returned by sqlite3_column_text16() always have the endianness +** which is native to the platform, regardless of the text encoding set +** for the database. +** ** Warning: ^The object returned by [sqlite3_column_value()] is an ** [unprotected sqlite3_value] object. In a multithreaded environment, ** an unprotected sqlite3_value object may only be used safely with @@ -4857,11 +5147,11 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** to routines like [sqlite3_value_int()], [sqlite3_value_text()], ** or [sqlite3_value_bytes()], the behavior is not threadsafe. ** Hence, the sqlite3_column_value() interface -** is normally only useful within the implementation of +** is normally only useful within the implementation of ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** -** The these routines may attempt to convert the datatype of the result. +** These routines may attempt to convert the datatype of the result. ** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions @@ -4886,7 +5176,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** TEXT BLOB No change ** BLOB INTEGER [CAST] to INTEGER ** BLOB FLOAT [CAST] to REAL -** BLOB TEXT Add a zero terminator if needed +** BLOB TEXT [CAST] to TEXT, ensure zero terminator ** ** )^ ** @@ -5010,20 +5300,33 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S ** back to the beginning of its program. ** -** ^If the most recent call to [sqlite3_step(S)] for the -** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], -** or if [sqlite3_step(S)] has never before been called on S, -** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** ^The return code from [sqlite3_reset(S)] indicates whether or not +** the previous evaluation of prepared statement S completed successfully. +** ^If [sqlite3_step(S)] has never before been called on S or if +** [sqlite3_step(S)] has not been called since the previous call +** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return +** [SQLITE_OK]. ** ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code]. +** ^The [sqlite3_reset(S)] interface might also return an [error code] +** if there were no prior errors but the process of resetting +** the prepared statement caused a new error. ^For example, if an +** [INSERT] statement with a [RETURNING] clause is only stepped one time, +** that one call to [sqlite3_step(S)] might return SQLITE_ROW but +** the overall statement might still fail and the [sqlite3_reset(S)] call +** might return SQLITE_BUSY if locking constraints prevent the +** database change from committing. Therefore, it is important that +** applications check the return code from [sqlite3_reset(S)] even if +** no prior call to [sqlite3_step(S)] indicated a problem. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -5032,8 +5335,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior ** of existing SQL functions or aggregates. The only differences between -** the three "sqlite3_create_function*" routines are the text encoding -** expected for the second parameter (the name of the function being +** the three "sqlite3_create_function*" routines are the text encoding +** expected for the second parameter (the name of the function being ** created) and the presence or absence of a destructor callback for ** the application data pointer. Function sqlite3_create_window_function() ** is similar, but allows the user to supply the extra callback functions @@ -5047,7 +5350,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ^The second parameter is the name of the SQL function to be created or ** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 ** representation, exclusive of the zero-terminator. ^Note that the name -** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. ** ^Any attempt to create a function with a longer name ** will result in [SQLITE_MISUSE] being returned. ** @@ -5062,7 +5365,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ^The fourth parameter, eTextRep, specifies what ** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** its parameters. The application should set this parameter to -** [SQLITE_UTF16LE] if the function implementation invokes +** [SQLITE_UTF16LE] if the function implementation invokes ** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the ** implementation invokes [sqlite3_value_text16be()] on an input, or ** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] @@ -5085,17 +5388,15 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** -** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be ** used inside of triggers, view, CHECK constraints, or other elements of -** the database schema. This flags is especially recommended for SQL +** the database schema. This flags is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters ** chosen by the attacker, which the application will then execute when ** the database file is opened and read. -** ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -5110,21 +5411,21 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** SQL function or aggregate, pass NULL pointers for all three function ** callbacks. ** -** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue ** and xInverse) passed to sqlite3_create_window_function are pointers to ** C-language callbacks that implement the new function. xStep and xFinal ** must both be non-NULL. xValue and xInverse may either both be NULL, in -** which case a regular aggregate function is created, or must both be +** which case a regular aggregate function is created, or must both be ** non-NULL, in which case the new function may be used as either an aggregate ** or aggregate window function. More details regarding the implementation -** of aggregate window functions are +** of aggregate window functions are ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or ** sqlite3_create_window_function() is not NULL, then it is destructor for -** the application data pointer. The destructor is invoked when the function -** is deleted, either by being overloaded or when the database connection -** closes.)^ ^The destructor is also invoked if the call to +** the application data pointer. The destructor is invoked when the function +** is deleted, either by being overloaded or when the database connection +** closes.)^ ^The destructor is also invoked if the call to ** sqlite3_create_function_v2() fails. ^When the destructor callback is ** invoked, it is passed a single argument which is a copy of the application ** data pointer which was the fifth parameter to sqlite3_create_function_v2(). @@ -5137,7 +5438,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** nArg parameter is a better match than a function implementation with ** a negative nArg. ^A function where the preferred text encoding ** matches the database encoding is a better -** match than a function where the encoding is different. +** match than a function where the encoding is different. ** ^A function where the encoding difference is between UTF16le and UTF16be ** is a closer match than a function where the encoding difference is ** between UTF8 and UTF16. @@ -5209,7 +5510,7 @@ SQLITE_API int sqlite3_create_window_function( /* ** CAPI3REF: Function Flags ** -** These constants may be ORed together with the +** These constants may be ORed together with the ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. @@ -5225,16 +5526,27 @@ SQLITE_API int sqlite3_create_window_function( ** SQLite might also optimize deterministic functions by factoring them ** out of inner loops. **
  • -** +** ** [[SQLITE_DIRECTONLY]]
    SQLITE_DIRECTONLY
    ** The SQLITE_DIRECTONLY flag means that the function may only be invoked -** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in ** schema structures such as [CHECK constraints], [DEFAULT clauses], ** [expression indexes], [partial indexes], or [generated columns]. -** The SQLITE_DIRECTONLY flags is a security feature which is recommended -** for all [application-defined SQL functions], and especially for functions -** that have side-effects or that could potentially leak sensitive -** information. +**

    +** The SQLITE_DIRECTONLY flag is recommended for any +** [application-defined SQL function] +** that has side-effects or that could potentially leak sensitive information. +** This will prevent attacks in which an application is tricked +** into using a database file that has had its schema surreptitiously +** modified to invoke the application-defined function in ways that are +** harmful. +**

    +** Some people say it is good practice to set SQLITE_DIRECTONLY on all +** [application-defined SQL functions], regardless of whether or not they +** are security sensitive, as doing so prevents those functions from being used +** inside of the database schema, and thus ensures that the database +** can be inspected and modified using generic tools (such as the [CLI]) +** that do not have access to the application-defined functions. **

    ** ** [[SQLITE_INNOCUOUS]]
    SQLITE_INNOCUOUS
    @@ -5281,7 +5593,7 @@ SQLITE_API int sqlite3_create_window_function( ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain -** backwards compatibility with older code, these functions continue +** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid ** the use of these functions. To encourage programmers to avoid ** these functions, we will not explain what they do. @@ -5349,11 +5661,11 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** -** ^If [sqlite3_value] object V was initialized +** ^If [sqlite3_value] object V was initialized ** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] ** and if X and Y are strings that compare equal according to strcmp(X,Y), ** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, -** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() +** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** ** ^(The sqlite3_value_type(V) interface returns the @@ -5440,6 +5752,28 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); SQLITE_API int sqlite3_value_nochange(sqlite3_value*); SQLITE_API int sqlite3_value_frombind(sqlite3_value*); +/* +** CAPI3REF: Report the internal text encoding state of an sqlite3_value object +** METHOD: sqlite3_value +** +** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], +** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding +** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) +** returns something other than SQLITE_TEXT, then the return value from +** sqlite3_value_encoding(X) is meaningless. ^Calls to +** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], +** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or +** [sqlite3_value_bytes16(X)] might change the encoding of the value X and +** thus change the return from subsequent calls to sqlite3_value_encoding(X). +** +** This routine is intended for used by applications that test and validate +** the SQLite implementation. This routine is inquiring about the opaque +** internal state of an [sqlite3_value] object. Ordinary applications should +** not need to know what the internal state of an sqlite3_value object is and +** hence should not need to use this interface. +*/ +SQLITE_API int sqlite3_value_encoding(sqlite3_value*); + /* ** CAPI3REF: Finding The Subtype Of SQL Values ** METHOD: sqlite3_value @@ -5460,7 +5794,8 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a -** memory allocation fails. +** memory allocation fails. ^If V is a [pointer value], then the result +** of sqlite3_value_dup(V) is a NULL value. ** ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer @@ -5476,7 +5811,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** -** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** ^The first time the sqlite3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite allocates ** N bytes of memory, zeroes out that memory, and returns a pointer ** to the new memory. ^On second and subsequent calls to @@ -5489,19 +5824,19 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); ** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** -** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory -** allocate error occurs. +** allocation error occurs. ** ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set -** N=0 in calls to sqlite3_aggregate_context(C,N) so that no +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no ** pointless memory allocations occur. ** -** ^SQLite automatically frees the memory allocated by +** ^SQLite automatically frees the memory allocated by ** sqlite3_aggregate_context() when the aggregate query concludes. ** ** The first parameter must be a copy of the @@ -5546,48 +5881,48 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to -** associate metadata with argument values. If the same value is passed to -** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. An example -** of where this might be useful is in a regular-expression matching -** function. The compiled version of the regular expression can be stored as -** metadata associated with the pattern string. +** associate auxiliary data with argument values. If the same argument +** value is passed to multiple invocations of the same SQL function during +** query execution, under some circumstances the associated auxiliary data +** might be preserved. An example of where this might be useful is in a +** regular-expression matching function. The compiled version of the regular +** expression can be stored as auxiliary data associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no metadata +** function argument. ^If there is no auxiliary data ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th -** argument of the application-defined function. ^Subsequent +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the +** N-th argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or -** NULL if the metadata has been discarded. +** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or +** NULL if the auxiliary data has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly -** once, when the metadata is discarded. -** SQLite is free to discard the metadata at any time, including: */ -SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); +SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only @@ -6184,6 +6606,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); */ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine the transaction state of a database +** METHOD: sqlite3 +** +** ^The sqlite3_txn_state(D,S) interface returns the current +** [transaction state] of schema S in database connection D. ^If S is NULL, +** then the highest transaction state of any schema on database connection D +** is returned. Transaction states are (in order of lowest to highest): +**
      +**
    1. SQLITE_TXN_NONE +**
    2. SQLITE_TXN_READ +**
    3. SQLITE_TXN_WRITE +**
    +** ^If the S argument to sqlite3_txn_state(D,S) is not the name of +** a valid schema, then -1 is returned. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); + +/* +** CAPI3REF: Allowed return values from sqlite3_txn_state() +** KEYWORDS: {transaction state} +** +** These constants define the current transaction state of a database file. +** ^The [sqlite3_txn_state(D,S)] interface returns one of these +** constants in order to describe the transaction state of schema S +** in [database connection] D. +** +**
    +** [[SQLITE_TXN_NONE]]
    SQLITE_TXN_NONE
    +**
    The SQLITE_TXN_NONE state means that no transaction is currently +** pending.
    +** +** [[SQLITE_TXN_READ]]
    SQLITE_TXN_READ
    +**
    The SQLITE_TXN_READ state means that the database is currently +** in a read transaction. Content has been read from the database file +** but nothing in the database file has changed. The transaction state +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** no other conflicting concurrent write transactions. The transaction +** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or +** [COMMIT].
    +** +** [[SQLITE_TXN_WRITE]]
    SQLITE_TXN_WRITE
    +**
    The SQLITE_TXN_WRITE state means that the database is currently +** in a write transaction. Content has been written to the database file +** but has not yet committed. The transaction state will change to +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
    +*/ +#define SQLITE_TXN_NONE 0 +#define SQLITE_TXN_READ 1 +#define SQLITE_TXN_WRITE 2 + /* ** CAPI3REF: Find the next prepared statement ** METHOD: sqlite3 @@ -6250,6 +6723,72 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +/* +** CAPI3REF: Autovacuum Compaction Amount Callback +** METHOD: sqlite3 +** +** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback +** function C that is invoked prior to each autovacuum of the database +** file. ^The callback is passed a copy of the generic data pointer (P), +** the schema-name of the attached database that is being autovacuumed, +** the size of the database file in pages, the number of free pages, +** and the number of bytes per page, respectively. The callback should +** return the number of free pages that should be removed by the +** autovacuum. ^If the callback returns zero, then no autovacuum happens. +** ^If the value returned is greater than or equal to the number of +** free pages, then a complete autovacuum happens. +** +**

    ^If there are multiple ATTACH-ed database files that are being +** modified as part of a transaction commit, then the autovacuum pages +** callback is invoked separately for each file. +** +**

    The callback is not reentrant. The callback function should +** not attempt to invoke any other SQLite interface. If it does, bad +** things may happen, including segmentation faults and corrupt database +** files. The callback function should be a simple function that +** does some arithmetic on its input parameters and returns a result. +** +** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional +** destructor for the P parameter. ^If X is not NULL, then X(P) is +** invoked whenever the database connection closes or when the callback +** is overwritten by another invocation of sqlite3_autovacuum_pages(). +** +**

    ^There is only one autovacuum pages callback per database connection. +** ^Each call to the sqlite3_autovacuum_pages() interface overrides all +** previous invocations for that database connection. ^If the callback +** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, +** then the autovacuum steps callback is canceled. The return value +** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might +** be some other error code if something goes wrong. The current +** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other +** return codes might be added in future releases. +** +**

    If no autovacuum pages callback is specified (the usual case) or +** a NULL pointer is provided for the callback, +** then the default behavior is to vacuum all free pages. So, in other +** words, the default behavior is the same as if the callback function +** were something like this: +** +**

    +**     unsigned int demonstration_autovac_pages_callback(
    +**       void *pClientData,
    +**       const char *zSchema,
    +**       unsigned int nDbPage,
    +**       unsigned int nFreePage,
    +**       unsigned int nBytePerPage
    +**     ){
    +**       return nFreePage;
    +**     }
    +** 
    +*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, + void(*)(void*) +); + + /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 @@ -6274,7 +6813,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^In the case of an update, this is the [rowid] after the update takes place. ** ** ^(The update hook is not invoked when internal system tables are -** modified (i.e. sqlite_master and sqlite_sequence).)^ +** modified (i.e. sqlite_sequence).)^ ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. ** ** ^In the current implementation, the update hook @@ -6300,7 +6839,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** and [sqlite3_preupdate_hook()] interfaces. */ SQLITE_API void *sqlite3_update_hook( - sqlite3*, + sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); @@ -6313,8 +6852,13 @@ SQLITE_API void *sqlite3_update_hook( ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** +** This interface is omitted if SQLite is compiled with +** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] +** compile-time option is recommended because the +** [use of shared cache mode is discouraged]. +** ** ^Cache sharing is enabled and disabled for an entire process. -** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). +** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). ** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** @@ -6335,8 +6879,8 @@ SQLITE_API void *sqlite3_update_hook( ** with the [SQLITE_OPEN_SHAREDCACHE] flag. ** ** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 -** and will always return SQLITE_MISUSE. On those systems, -** shared cache mode should be enabled per-database connection via +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via ** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a @@ -6389,7 +6933,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** as heap memory usages approaches the limit. ** ^The soft heap limit is "soft" because even though SQLite strives to stay ** below the limit, it will exceed the limit rather than generate -** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** an [SQLITE_NOMEM] error. In other words, the soft heap limit ** is advisory only. ** ** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of @@ -6411,7 +6955,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); ** ^The soft heap limit may not be greater than the hard heap limit. ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) ** is invoked with a value of N that is greater than the hard heap limit, -** the the soft heap limit is set to the value of the hard heap limit. +** the soft heap limit is set to the value of the hard heap limit. ** ^The soft heap limit is automatically enabled whenever the hard heap ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and ** the soft heap limit is outside the range of 1..N, then the soft heap @@ -6505,7 +7049,7 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** ** ^If the specified table is actually a view, an [error code] is returned. ** -** ^If the specified column is "rowid", "oid" or "_rowid_" and the table +** ^If the specified column is "rowid", "oid" or "_rowid_" and the table ** is not a [WITHOUT ROWID] table and an ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output ** parameters are set for the explicitly declared column. ^(If there is no @@ -6571,7 +7115,7 @@ SQLITE_API int sqlite3_table_column_metadata( ** prior to calling this API, ** otherwise an error will be returned. ** -** Security warning: It is recommended that the +** Security warning: It is recommended that the ** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this ** interface. The use of the [sqlite3_enable_load_extension()] interface ** should be avoided. This will keep the SQL function [load_extension()] @@ -6658,7 +7202,7 @@ SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void)); ** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the ** initialization routine X that was registered using a prior call to ** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] -** routine returns 1 if initialization routine X was successfully +** routine returns 1 if initialization routine X was successfully ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ @@ -6672,15 +7216,6 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); */ SQLITE_API void sqlite3_reset_auto_extension(void); -/* -** The interface to the virtual-table mechanism is currently considered -** to be experimental. The interface might change in incompatible ways. -** If this is a problem for you, do not use the interface at this time. -** -** When the virtual-table mechanism stabilizes, we will declare the -** interface fixed, support it indefinitely, and remove this comment. -*/ - /* ** Structures used by the virtual table interface */ @@ -6693,8 +7228,8 @@ typedef struct sqlite3_module sqlite3_module; ** CAPI3REF: Virtual Table Object ** KEYWORDS: sqlite3_module {virtual table module} ** -** This structure, sometimes called a "virtual table module", -** defines the implementation of a [virtual table]. +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual table]. ** This structure consists mostly of methods for the module. ** ** ^A virtual table module is created by filling in a persistent @@ -6733,7 +7268,7 @@ struct sqlite3_module { void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); - /* The methods above are in version 1 of the sqlite_module object. Those + /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ int (*xSavepoint)(sqlite3_vtab *pVTab, int); int (*xRelease)(sqlite3_vtab *pVTab, int); @@ -6741,6 +7276,10 @@ struct sqlite3_module { /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); + /* The methods above are in versions 1 through 3 of the sqlite_module object. + ** Those below are for version 4 and greater. */ + int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, + const char *zTabName, int mFlags, char **pzErr); }; /* @@ -6783,7 +7322,7 @@ struct sqlite3_module { ** required by SQLite. If the table has at least 64 columns and any column ** to the right of the first 63 is required, then bit 63 of colUsed is also ** set. In other words, column iCol may be required if the expression -** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to +** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to ** non-zero. ** ** The [xBestIndex] method must fill aConstraintUsage[] with information @@ -6799,10 +7338,10 @@ struct sqlite3_module { ** when the omit flag is true there is no guarantee that the constraint will ** not be checked again using byte code.)^ ** -** ^The idxNum and idxPtr values are recorded and passed into the +** ^The idxNum and idxStr values are recorded and passed into the ** [xFilter] method. -** ^[sqlite3_free()] is used to free idxPtr if and only if -** needToFreeIdxPtr is true. +** ^[sqlite3_free()] is used to free idxStr if and only if +** needToFreeIdxStr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate @@ -6810,17 +7349,17 @@ struct sqlite3_module { ** ** ^The estimatedCost value is an estimate of the cost of a particular ** strategy. A cost of N indicates that the cost of the strategy is similar -** to a linear scan of an SQLite table with N rows. A cost of log(N) +** to a linear scan of an SQLite table with N rows. A cost of log(N) ** indicates that the expense of the operation is similar to that of a ** binary search on a unique indexed field of an SQLite table with N rows. ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** -** The xBestIndex method may optionally populate the idxFlags field with a +** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite -** assumes that the strategy may visit at most one row. +** assumes that the strategy may visit at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as @@ -6833,14 +7372,14 @@ struct sqlite3_module { ** the xUpdate method are automatically rolled back by SQLite. ** ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info -** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). +** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). ** If a virtual table extension is -** used with an SQLite version earlier than 3.8.2, the results of attempting -** to read or write the estimatedRows field are undefined (but are likely +** used with an SQLite version earlier than 3.8.2, the results of attempting +** to read or write the estimatedRows field are undefined (but are likely ** to include crashing the application). The estimatedRows field should ** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. Similarly, the idxFlags field -** was added for [version 3.9.0] ([dateof:3.9.0]). +** was added for [version 3.9.0] ([dateof:3.9.0]). ** It may therefore only be used if ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. @@ -6880,7 +7419,7 @@ struct sqlite3_index_info { /* ** CAPI3REF: Virtual Table Scan Flags ** -** Virtual table implementations are allowed to set the +** Virtual table implementations are allowed to set the ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ @@ -6891,24 +7430,56 @@ struct sqlite3_index_info { ** ** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents -** an operator that is part of a constraint term in the wHERE clause of +** an operator that is part of a constraint term in the WHERE clause of ** a query that uses a [virtual table]. -*/ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -#define SQLITE_INDEX_CONSTRAINT_NE 68 -#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -#define SQLITE_INDEX_CONSTRAINT_IS 72 -#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 +** +** ^The left-hand operand of the operator is given by the corresponding +** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand +** operand is the rowid. +** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET +** operators have no left-hand operand, and so for those operators the +** corresponding aConstraint[].iColumn is meaningless and should not be +** used. +** +** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through +** value 255 are reserved to represent functions that are overloaded +** by the [xFindFunction|xFindFunction method] of the virtual table +** implementation. +** +** The right-hand operands for each constraint might be accessible using +** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand +** operand is only available if it appears as a single constant literal +** in the input SQL. If the right-hand operand is another column or an +** expression (even a constant expression) or a parameter, then the +** sqlite3_vtab_rhs_value() probably will not be able to extract it. +** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and +** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand +** and hence calls to sqlite3_vtab_rhs_value() for those operators will +** always return SQLITE_NOTFOUND. +** +** The collating sequence to be used for comparison can be found using +** the [sqlite3_vtab_collation()] interface. For most real-world virtual +** tables, the collating sequence of constraints does not matter (for example +** because the constraints are numeric) and so the sqlite3_vtab_collation() +** interface is not commonly needed. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -6920,7 +7491,7 @@ struct sqlite3_index_info { ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified -** by the first parameter. ^The name of the module is given by the +** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through @@ -6937,7 +7508,7 @@ struct sqlite3_index_info { ** destructor. ** ** ^If the third parameter (the pointer to the sqlite3_module object) is -** NULL then no new module is create and any existing modules with the +** NULL then no new module is created and any existing modules with the ** same name are dropped. ** ** See also: [sqlite3_drop_modules()] @@ -7035,7 +7606,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); ** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions -** using the [xFindFunction] method of the [virtual table module]. +** using the [xFindFunction] method of the [virtual table module]. ** But global versions of those functions ** must exist in order to be overloaded.)^ ** @@ -7049,16 +7620,6 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); */ SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); -/* -** The interface to the virtual-table mechanism defined above (back up -** to a comment remarkably similar to this one) is currently considered -** to be experimental. The interface might change in incompatible ways. -** If this is a problem for you, do not use the interface at this time. -** -** When the virtual-table mechanism stabilizes, we will declare the -** interface fixed, support it indefinitely, and remove this comment. -*/ - /* ** CAPI3REF: A Handle To An Open BLOB ** KEYWORDS: {BLOB handle} {BLOB handles} @@ -7086,7 +7647,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; ** )^ ** -** ^(Parameter zDb is not the filename that contains the database, but +** ^(Parameter zDb is not the filename that contains the database, but ** rather the symbolic name of the database. For attached databases, this is ** the name that appears after the AS keyword in the [ATTACH] statement. ** For the main database file, the database name is "main". For TEMP @@ -7099,28 +7660,28 @@ typedef struct sqlite3_blob sqlite3_blob; ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided -** the API is not misused, it is always safe to call [sqlite3_blob_close()] +** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** on *ppBlob after this function it returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: **
      -**
    • ^(Database zDb does not exist)^, -**
    • ^(Table zTable does not exist within database zDb)^, -**
    • ^(Table zTable is a WITHOUT ROWID table)^, +**
    • ^(Database zDb does not exist)^, +**
    • ^(Table zTable does not exist within database zDb)^, +**
    • ^(Table zTable is a WITHOUT ROWID table)^, **
    • ^(Column zColumn does not exist)^, **
    • ^(Row iRow is not present in the table)^, **
    • ^(The specified column of row iRow contains a value that is not ** a TEXT or BLOB value)^, -**
    • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE +**
    • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE ** constraint and the blob is being opened for read/write access)^, -**
    • ^([foreign key constraints | Foreign key constraints] are enabled, +**
    • ^([foreign key constraints | Foreign key constraints] are enabled, ** column zColumn is part of a [child key] definition and the blob is ** being opened for read/write access)^. **
    ** -** ^Unless it returns SQLITE_MISUSE, this function sets the -** [database connection] error code and message accessible via -** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** ^Unless it returns SQLITE_MISUSE, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** ** A BLOB referenced by sqlite3_blob_open() may be read using the ** [sqlite3_blob_read()] interface and modified by using @@ -7146,7 +7707,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** blob. ** ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces -** and the built-in [zeroblob] SQL function may be used to create a +** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually @@ -7196,7 +7757,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); ** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed -** unconditionally. Even if this routine returns an error code, the +** unconditionally. Even if this routine returns an error code, the ** handle is still closed.)^ ** ** ^If the blob handle being closed was opened for read-write access, and if @@ -7206,10 +7767,10 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behaviour. ^Calling this routine -** with a null pointer (such as would be returned by a failed call to +** open blob handle results in undefined behavior. ^Calling this routine +** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function -** is passed a valid open blob handle, the values returned by the +** is passed a valid open blob handle, the values returned by the ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); @@ -7218,7 +7779,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** -** ^Returns the size in bytes of the BLOB accessible via the +** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. @@ -7269,9 +7830,9 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); ** ** ^(On success, sqlite3_blob_write() returns SQLITE_OK. ** Otherwise, an [error code] or an [extended error code] is returned.)^ -** ^Unless SQLITE_MISUSE is returned, this function sets the -** [database connection] error code and message accessible via -** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** ^Unless SQLITE_MISUSE is returned, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** ** ^If the [BLOB handle] passed as the first argument was not opened for ** writing (the flags parameter to [sqlite3_blob_open()] was zero), @@ -7280,9 +7841,9 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); ** This function may only modify the contents of the BLOB; it is ** not possible to increase the size of a BLOB using this API. ** ^If offset iOffset is less than N bytes from the end of the BLOB, -** [SQLITE_ERROR] is returned and no data is written. The size of the -** BLOB (and hence the maximum value of N+iOffset) can be determined -** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less +** [SQLITE_ERROR] is returned and no data is written. The size of the +** BLOB (and hence the maximum value of N+iOffset) can be determined +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less ** than zero [SQLITE_ERROR] is returned and no data is written. ** ** ^An attempt to write to an expired [BLOB handle] fails with an @@ -7376,7 +7937,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); **
      **
    • SQLITE_MUTEX_FAST **
    • SQLITE_MUTEX_RECURSIVE -**
    • SQLITE_MUTEX_STATIC_MASTER +**
    • SQLITE_MUTEX_STATIC_MAIN **
    • SQLITE_MUTEX_STATIC_MEM **
    • SQLITE_MUTEX_STATIC_OPEN **
    • SQLITE_MUTEX_STATIC_PRNG @@ -7434,7 +7995,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() ** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable +** sqlite3_mutex_try() as an optimization so this is acceptable ** behavior.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was @@ -7442,9 +8003,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** is undefined if the mutex is not currently entered by the ** calling thread or is not currently allocated. ** -** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or -** sqlite3_mutex_leave() is a NULL pointer, then all three routines -** behave as no-ops. +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), +** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, +** then any of the four routines behaves as a no-op. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ @@ -7578,7 +8139,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); */ #define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_RECURSIVE 1 -#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MAIN 2 #define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ #define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ @@ -7593,11 +8154,15 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); #define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */ #define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */ +/* Legacy compatibility: */ +#define SQLITE_MUTEX_STATIC_MASTER 2 + + /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** -** ^This interface returns a pointer the [sqlite3_mutex] object that +** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -7624,7 +8189,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** method becomes the return value of this routine. ** ** A few opcodes for [sqlite3_file_control()] are handled directly -** by the SQLite core and never invoke the +** by the SQLite core and never invoke the ** sqlite3_io_methods.xFileControl method. ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes ** a pointer to the underlying [sqlite3_file] object to be written into @@ -7682,6 +8247,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ +#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -7706,12 +8272,17 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 -#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_TUNE 32 +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_USELONGDOUBLE 34 +#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** -** These routines provide access to the set of SQL language keywords +** These routines provide access to the set of SQL language keywords ** recognized by SQLite. Applications can uses these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. @@ -7783,14 +8354,14 @@ typedef struct sqlite3_str sqlite3_str; ** ** ^The [sqlite3_str_new(D)] interface allocates and initializes ** a new [sqlite3_str] object. To avoid memory leaks, the object returned by -** [sqlite3_str_new()] must be freed by a subsequent call to +** [sqlite3_str_new()] must be freed by a subsequent call to ** [sqlite3_str_finish(X)]. ** ** ^The [sqlite3_str_new(D)] interface always returns a pointer to a ** valid [sqlite3_str] object, though in the event of an out-of-memory ** error the returned object might be a special singleton that will -** silently reject new text, always return SQLITE_NOMEM from -** [sqlite3_str_errcode()], always return 0 for +** silently reject new text, always return SQLITE_NOMEM from +** [sqlite3_str_errcode()], always return 0 for ** [sqlite3_str_length()], and always return NULL from ** [sqlite3_str_finish(X)]. It is always safe to use the value ** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter @@ -7826,9 +8397,9 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); ** These interfaces add content to an sqlite3_str object previously obtained ** from [sqlite3_str_new()]. ** -** ^The [sqlite3_str_appendf(X,F,...)] and +** ^The [sqlite3_str_appendf(X,F,...)] and ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] -** functionality of SQLite to append formatted text onto the end of +** functionality of SQLite to append formatted text onto the end of ** [sqlite3_str] object X. ** ** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S @@ -7845,7 +8416,7 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); ** ^This method can be used, for example, to add whitespace indentation. ** ** ^The [sqlite3_str_reset(X)] method resets the string under construction -** inside [sqlite3_str] object X back to zero bytes in length. +** inside [sqlite3_str] object X back to zero bytes in length. ** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a @@ -7947,7 +8518,7 @@ SQLITE_API int sqlite3_status64( **
      This parameter records the largest memory allocation request ** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their ** internal equivalents). Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
      )^ ** ** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
      SQLITE_STATUS_MALLOC_COUNT
      @@ -7956,11 +8527,11 @@ SQLITE_API int sqlite3_status64( ** ** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
      SQLITE_STATUS_PAGECACHE_USED
      **
      This parameter returns the number of pages used out of the -** [pagecache memory allocator] that was configured using +** [pagecache memory allocator] that was configured using ** [SQLITE_CONFIG_PAGECACHE]. The ** value returned is in pages, not in bytes.
      )^ ** -** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(
      SQLITE_STATUS_PAGECACHE_OVERFLOW
      **
      This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] @@ -7973,7 +8544,7 @@ SQLITE_API int sqlite3_status64( ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
      SQLITE_STATUS_PAGECACHE_SIZE
      **
      This parameter records the largest memory allocation request ** handed to the [pagecache memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
      )^ ** ** [[SQLITE_STATUS_SCRATCH_USED]]
      SQLITE_STATUS_SCRATCH_USED
      @@ -7986,7 +8557,7 @@ SQLITE_API int sqlite3_status64( **
      No longer used.
      ** ** [[SQLITE_STATUS_PARSER_STACK]] ^(
      SQLITE_STATUS_PARSER_STACK
      -**
      The *pHighwater parameter records the deepest parser stack. +**
      The *pHighwater parameter records the deepest parser stack. ** The *pCurrent value is undefined. The *pHighwater value is only ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
      )^ **
    @@ -8008,12 +8579,12 @@ SQLITE_API int sqlite3_status64( ** CAPI3REF: Database Connection Status ** METHOD: sqlite3 ** -** ^This interface is used to retrieve runtime status information +** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the ** database connection object to be interrogated. ^The second argument ** is an integer constant, taken from the set of ** [SQLITE_DBSTATUS options], that -** determines the parameter to interrogate. The set of +** determines the parameter to interrogate. The set of ** [SQLITE_DBSTATUS options] is likely ** to grow in future releases of SQLite. ** @@ -8048,7 +8619,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** checked out.
    )^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_HIT
    -**
    This parameter returns the number of malloc attempts that were +**
    This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; ** the current value is always zero.)^ ** @@ -8073,7 +8644,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** -** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] +** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(
    SQLITE_DBSTATUS_CACHE_USED_SHARED
    **
    This parameter is similar to DBSTATUS_CACHE_USED, except that if a ** pager cache is shared between two or more connections the bytes of heap @@ -8088,7 +8659,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    **
    This parameter returns the approximate number of bytes of heap ** memory used to store the schema for all databases associated -** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ ** ^The full amount of memory used by the schemas is reported, even if the ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. @@ -8103,13 +8674,13 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** ** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
    SQLITE_DBSTATUS_CACHE_HIT
    **
    This parameter returns the number of pager cache hits that have -** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT ** is always 0. **
    ** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
    SQLITE_DBSTATUS_CACHE_MISS
    **
    This parameter returns the number of pager cache misses that have -** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. **
    ** @@ -8167,7 +8738,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate ** that the prepared statement is using a full table scan rather than -** an index. +** an index. ** ** ^(This interface is used to retrieve and reset counter values from ** a [prepared statement]. The first argument is the prepared statement @@ -8194,7 +8765,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
    SQLITE_STMTSTATUS_FULLSCAN_STEP
    **
    ^This is the number of times that SQLite has stepped forward in ** a table as part of a full table scan. Large numbers for this counter -** may indicate opportunities for performance improvement through +** may indicate opportunities for performance improvement through ** careful use of indices.
    ** ** [[SQLITE_STMTSTATUS_SORT]]
    SQLITE_STMTSTATUS_SORT
    @@ -8212,14 +8783,14 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** [[SQLITE_STMTSTATUS_VM_STEP]]
    SQLITE_STMTSTATUS_VM_STEP
    **
    ^This is the number of virtual machine operations executed ** by the prepared statement if that number is less than or equal -** to 2147483647. The number of virtual machine operations can be +** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 ** then the value returned by this statement status code is undefined. ** ** [[SQLITE_STMTSTATUS_REPREPARE]]
    SQLITE_STMTSTATUS_REPREPARE
    **
    ^This is the number of times that the prepare statement has been -** automatically regenerated due to schema changes or changes to +** automatically regenerated due to schema changes or changes to ** [bound parameters] that might affect the query plan. ** ** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    @@ -8229,6 +8800,16 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle. ** +** [[SQLITE_STMTSTATUS_FILTER_MISS]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] +**
    SQLITE_STMTSTATUS_FILTER_HIT
    +** SQLITE_STMTSTATUS_FILTER_MISS
    +**
    ^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join +** step was bypassed because a Bloom filter returned not-found. The +** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of +** times that the Bloom filter returned a find, and thus the join step +** had to be processed as normal. +** ** [[SQLITE_STMTSTATUS_MEMUSED]]
    SQLITE_STMTSTATUS_MEMUSED
    **
    ^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually @@ -8243,6 +8824,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_VM_STEP 4 #define SQLITE_STMTSTATUS_REPREPARE 5 #define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_FILTER_MISS 7 +#define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 /* @@ -8279,15 +8862,15 @@ struct sqlite3_pcache_page { ** KEYWORDS: {page cache} ** ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can -** register an alternative page cache implementation by passing in an +** register an alternative page cache implementation by passing in an ** instance of the sqlite3_pcache_methods2 structure.)^ -** In many applications, most of the heap memory allocated by +** In many applications, most of the heap memory allocated by ** SQLite is used for the page cache. -** By implementing a +** By implementing a ** custom page cache using this API, an application can better control -** the amount of memory consumed by SQLite, the way in which -** that memory is allocated and released, and the policies used to -** determine exactly which parts of a database file are cached and for +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for ** how long. ** ** The alternative page cache mechanism is an @@ -8300,19 +8883,19 @@ struct sqlite3_pcache_page { ** [sqlite3_config()] returns.)^ ** ** [[the xInit() page cache method]] -** ^(The xInit() method is called once for each effective +** ^(The xInit() method is called once for each effective ** call to [sqlite3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() ** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ -** The intent of the xInit() method is to set up global data structures -** required by the custom page cache implementation. -** ^(If the xInit() method is NULL, then the +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache.)^ ** ** [[the xShutdown() page cache method]] ** ^The xShutdown() method is called by [sqlite3_shutdown()]. -** It can be used to clean up +** It can be used to clean up ** any outstanding resources before process shutdown, if required. ** ^The xShutdown() method may be NULL. ** @@ -8331,7 +8914,7 @@ struct sqlite3_pcache_page { ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must ** be allocated by the cache. ^szPage will always a power of two. ^The -** second parameter szExtra is a number of bytes of extra storage +** second parameter szExtra is a number of bytes of extra storage ** associated with each page cache entry. ^The szExtra parameter will ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying @@ -8344,7 +8927,7 @@ struct sqlite3_pcache_page { ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to -** false will always have the "discard" flag set to true. +** false will always have the "discard" flag set to true. ** ^Hence, a cache created with bPurgeable false will ** never contain any unpinned pages. ** @@ -8359,12 +8942,12 @@ struct sqlite3_pcache_page { ** [[the xPagecount() page cache methods]] ** The xPagecount() method must return the number of pages currently ** stored in the cache, both pinned and unpinned. -** +** ** [[the xFetch() page cache methods]] -** The xFetch() method locates a page in the cache and returns a pointer to +** The xFetch() method locates a page in the cache and returns a pointer to ** an sqlite3_pcache_page object associated with that page, or a NULL pointer. ** The pBuf element of the returned sqlite3_pcache_page object will be a -** pointer to a buffer of szPage bytes used to store the content of a +** pointer to a buffer of szPage bytes used to store the content of a ** single database page. The pExtra element of sqlite3_pcache_page will be ** a pointer to the szExtra bytes of extra storage that SQLite has requested ** for each entry in the page cache. @@ -8403,8 +8986,8 @@ struct sqlite3_pcache_page { ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** -** The cache must not perform any reference counting. A single -** call to xUnpin() unpins the page regardless of the number of prior calls +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls ** to xFetch(). ** ** [[the xRekey() page cache methods]] @@ -8444,7 +9027,7 @@ struct sqlite3_pcache_methods2 { int (*xPagecount)(sqlite3_pcache*); sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); - void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, unsigned oldKey, unsigned newKey); void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); void (*xDestroy)(sqlite3_pcache*); @@ -8489,7 +9072,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** ** The backup API copies the content of one database into another. ** It is useful either for creating backups of databases or -** for copying in-memory databases to or from persistent files. +** for copying in-memory databases to or from persistent files. ** ** See Also: [Using the SQLite Online Backup API] ** @@ -8500,36 +9083,36 @@ typedef struct sqlite3_backup sqlite3_backup; ** ^Thus, the backup may be performed on a live source database without ** preventing other database connections from ** reading or writing to the source database while the backup is underway. -** -** ^(To perform a backup operation: +** +** ^(To perform a backup operation: **
      **
    1. sqlite3_backup_init() is called once to initialize the -** backup, -**
    2. sqlite3_backup_step() is called one or more times to transfer +** backup, +**
    3. sqlite3_backup_step() is called one or more times to transfer ** the data between the two databases, and finally -**
    4. sqlite3_backup_finish() is called to release all resources -** associated with the backup operation. +**
    5. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. **
    )^ ** There should be exactly one call to sqlite3_backup_finish() for each ** successful call to sqlite3_backup_init(). ** ** [[sqlite3_backup_init()]] sqlite3_backup_init() ** -** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the -** [database connection] associated with the destination database +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database ** and the database name, respectively. ** ^The database name is "main" for the main database, "temp" for the ** temporary database, or the name specified after the AS keyword in ** an [ATTACH] statement for an attached database. -** ^The S and M arguments passed to +** ^The S and M arguments passed to ** sqlite3_backup_init(D,N,S,M) identify the [database connection] ** and database name of the source database, respectively. ** ^The source and destination [database connections] (parameters S and D) ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with ** an error. ** -** ^A call to sqlite3_backup_init() will fail, returning NULL, if -** there is already a read or read-write transaction open on the +** ^A call to sqlite3_backup_init() will fail, returning NULL, if +** there is already a read or read-write transaction open on the ** destination database. ** ** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is @@ -8541,14 +9124,14 @@ typedef struct sqlite3_backup sqlite3_backup; ** ^A successful call to sqlite3_backup_init() returns a pointer to an ** [sqlite3_backup] object. ** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and -** sqlite3_backup_finish() functions to perform the specified backup +** sqlite3_backup_finish() functions to perform the specified backup ** operation. ** ** [[sqlite3_backup_step()]] sqlite3_backup_step() ** -** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between ** the source and destination databases specified by [sqlite3_backup] object B. -** ^If N is negative, all remaining source pages are copied. +** ^If N is negative, all remaining source pages are copied. ** ^If sqlite3_backup_step(B,N) successfully copies N pages and there ** are still more pages to be copied, then the function returns [SQLITE_OK]. ** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages @@ -8570,8 +9153,8 @@ typedef struct sqlite3_backup sqlite3_backup; ** ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then ** the [sqlite3_busy_handler | busy-handler function] -** is invoked (if one is specified). ^If the -** busy-handler returns non-zero before the lock is available, then +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then ** [SQLITE_BUSY] is returned to the caller. ^In this case the call to ** sqlite3_backup_step() can be retried later. ^If the source ** [database connection] @@ -8579,15 +9162,15 @@ typedef struct sqlite3_backup sqlite3_backup; ** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this ** case the call to sqlite3_backup_step() can be retried later on. ^(If ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or -** [SQLITE_READONLY] is returned, then -** there is no point in retrying the call to sqlite3_backup_step(). These -** errors are considered fatal.)^ The application must accept -** that the backup operation has failed and pass the backup operation handle +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle ** to the sqlite3_backup_finish() to release associated resources. ** ** ^The first call to sqlite3_backup_step() obtains an exclusive lock -** on the destination file. ^The exclusive lock is not released until either -** sqlite3_backup_finish() is called or the backup operation is complete +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete ** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to ** sqlite3_backup_step() obtains a [shared lock] on the source database that ** lasts for the duration of the sqlite3_backup_step() call. @@ -8596,18 +9179,18 @@ typedef struct sqlite3_backup sqlite3_backup; ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically -** restarted by the next call to sqlite3_backup_step(). ^If the source +** restarted by the next call to sqlite3_backup_step(). ^If the source ** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** ** [[sqlite3_backup_finish()]] sqlite3_backup_finish() ** -** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the ** application wishes to abandon the backup operation, the application ** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). ** ^The sqlite3_backup_finish() interfaces releases all -** resources associated with the [sqlite3_backup] object. +** resources associated with the [sqlite3_backup] object. ** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any ** active write-transaction on the destination database is rolled back. ** The [sqlite3_backup] object is invalid @@ -8647,23 +9230,23 @@ typedef struct sqlite3_backup sqlite3_backup; ** connections, then the source database connection may be used concurrently ** from within other threads. ** -** However, the application must guarantee that the destination -** [database connection] is not passed to any other API (by any thread) after +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after ** sqlite3_backup_init() is called and before the corresponding call to ** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] ** and so no error code is reported, but the operations may malfunction ** nevertheless. Use of the destination database connection while a -** backup is in progress might also also cause a mutex deadlock. +** backup is in progress might also cause a mutex deadlock. ** ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means -** that the application must guarantee that the disk file being +** that the application must guarantee that the disk file being ** backed up to is not accessed by any connection within the process, ** not just the specific connection that was passed to sqlite3_backup_init(). ** -** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the @@ -8688,8 +9271,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or ** individual tables within the shared-cache cannot be obtained. See -** [SQLite Shared-Cache Mode] for a description of shared-cache locking. -** ^This API may be used to register a callback that SQLite will invoke +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke ** when the connection currently holding the required lock relinquishes it. ** ^This API is only available if the library was compiled with the ** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. @@ -8697,14 +9280,14 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** See Also: [Using the SQLite Unlock Notification Feature]. ** ** ^Shared-cache locks are released when a database connection concludes -** its current transaction, either by committing it or rolling it back. +** its current transaction, either by committing it or rolling it back. ** ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that -** has locked the required resource is stored internally. ^After an +** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the -** sqlite3_unlock_notify() method with the blocked connection handle as +** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] @@ -8718,15 +9301,15 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds -** a read-lock on the same table, then SQLite arbitrarily selects one of +** a read-lock on the same table, then SQLite arbitrarily selects one of ** the other connections to use as the blocking connection. ** -** ^(There may be at most one unlock-notify callback registered by a +** ^(There may be at most one unlock-notify callback registered by a ** blocked connection. If sqlite3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** @@ -8739,7 +9322,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ** Callback Invocation Details ** -** When an unlock-notify callback is registered, the application provides a +** When an unlock-notify callback is registered, the application provides a ** single void* pointer that is passed to the callback when it is invoked. ** However, the signature of the callback function allows SQLite to pass ** it an array of void* context pointers. The first argument passed to @@ -8752,12 +9335,12 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** same callback function, then instead of invoking the callback function ** multiple times, it is invoked once with the set of void* context pointers ** specified by the blocked connections bundled together into an array. -** This gives the application an opportunity to prioritize any actions +** This gives the application an opportunity to prioritize any actions ** related to the set of unblocked database connections. ** ** Deadlock Detection ** -** Assuming that after registering for an unlock-notify callback a +** Assuming that after registering for an unlock-notify callback a ** database waits for the callback to be issued before taking any further ** action (a reasonable assumption), then using this API may cause the ** application to deadlock. For example, if connection X is waiting for @@ -8780,7 +9363,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** ** The "DROP TABLE" Exception ** -** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost ** always appropriate to call sqlite3_unlock_notify(). There is however, ** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, ** SQLite checks if there are any currently executing SELECT statements @@ -8793,7 +9376,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in -** the special "DROP TABLE/INDEX" case, the extended error code is just +** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ SQLITE_API int sqlite3_unlock_notify( @@ -8884,8 +9467,8 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); ** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. ** -** ^(The callback is invoked by SQLite after the commit has taken place and -** the associated write-lock on the database released)^, so the implementation +** ^(The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released)^, so the implementation ** may read, write or [checkpoint] the database as required. ** ** ^The first parameter passed to the callback function when it is invoked @@ -8904,15 +9487,16 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); ** that does not correspond to any valid SQLite error code, the results ** are undefined. ** -** A single database handle may have at most a single write-ahead log callback +** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any -** previously registered write-ahead log callback. ^Note that the -** [sqlite3_wal_autocheckpoint()] interface and the +** previously registered write-ahead log callback. ^The return value is +** a copy of the third parameter from the previous call, if any, or 0. +** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** overwrite any prior [sqlite3_wal_hook()] settings. */ SQLITE_API void *sqlite3_wal_hook( - sqlite3*, + sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* ); @@ -8925,7 +9509,7 @@ SQLITE_API void *sqlite3_wal_hook( ** [sqlite3_wal_hook()] that causes any database on [database connection] D ** to automatically [checkpoint] ** after committing a transaction if there are N or -** more frames in the [write-ahead log] file. ^Passing zero or +** more frames in the [write-ahead log] file. ^Passing zero or ** a negative value as the nFrame parameter disables automatic ** checkpoints entirely. ** @@ -8955,7 +9539,7 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ ** -** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the ** [write-ahead log] for database X on [database connection] D to be ** transferred into the database file and for the write-ahead log to ** be reset. See the [checkpointing] documentation for addition @@ -8981,10 +9565,10 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); ** **
    **
    SQLITE_CHECKPOINT_PASSIVE
    -** ^Checkpoint as many frames as possible without waiting for any database -** readers or writers to finish, then sync the database file if all frames +** ^Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish, then sync the database file if all frames ** in the log were checkpointed. ^The [busy-handler callback] -** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. ** ^On the other hand, passive mode might leave the checkpoint unfinished ** if there are concurrent readers or writers. ** @@ -8998,9 +9582,9 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); ** **
    SQLITE_CHECKPOINT_RESTART
    ** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition -** that after checkpointing the log file it blocks (calls the +** that after checkpointing the log file it blocks (calls the ** [busy-handler callback]) -** until all readers are reading from the database file only. ^This ensures +** until all readers are reading from the database file only. ^This ensures ** that the next writer will restart the log file from the beginning. ** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new ** database writer attempts while it is pending, but does not impede readers. @@ -9022,31 +9606,31 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); ** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. ** ** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If -** any other process is running a checkpoint operation at the same time, the -** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a ** busy-handler configured, it will not be invoked in this case. ** -** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the ** exclusive "writer" lock on the database file. ^If the writer lock cannot be ** obtained immediately, and a busy-handler is configured, it is invoked and ** the writer lock retried until either the busy-handler returns 0 or the lock ** is successfully obtained. ^The busy-handler is also invoked while waiting for ** database readers as described above. ^If the busy-handler returns 0 before ** the writer lock is obtained or while waiting for database readers, the -** checkpoint operation proceeds from that point in the same way as -** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible ** without blocking any further. ^SQLITE_BUSY is returned in this case. ** ** ^If parameter zDb is NULL or points to a zero length string, then the -** specified operation is attempted on all WAL databases [attached] to +** specified operation is attempted on all WAL databases [attached] to ** [database connection] db. In this case the -** values written to output parameters *pnLog and *pnCkpt are undefined. ^If -** an SQLITE_BUSY error is encountered when processing one or more of the -** attached WAL databases, the operation is still attempted on any remaining -** attached databases and SQLITE_BUSY is returned at the end. ^If any other -** error occurs while processing an attached database, processing is abandoned -** and the error code is returned to the caller immediately. ^If no error -** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned at the end. ^If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code is returned to the caller immediately. ^If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached ** databases, SQLITE_OK is returned. ** ** ^If database zDb is the name of an attached database that is not in WAL @@ -9081,7 +9665,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( */ #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ -#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ /* @@ -9106,7 +9690,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options -** KEYWORDS: {virtual table configuration options} +** KEYWORDS: {virtual table configuration options} ** KEYWORDS: {virtual table configuration option} ** ** These macros define the various options to the @@ -9129,27 +9713,27 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** If X is non-zero, then the virtual table implementation guarantees ** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before ** any modifications to internal or persistent data structures have been made. -** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite ** is able to roll back a statement or database transaction, and abandon -** or continue processing the current SQL statement as appropriate. +** or continue processing the current SQL statement as appropriate. ** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns ** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode ** had been ABORT. ** ** Virtual table implementations that are required to handle OR REPLACE -** must do so within the [xUpdate] method. If a call to the -** [sqlite3_vtab_on_conflict()] function indicates that the current ON -** CONFLICT policy is REPLACE, the virtual table implementation should +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should ** silently replace the appropriate rows within the xUpdate callback and ** return SQLITE_OK. Or, if this is not possible, it may return -** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. **
    ** ** [[SQLITE_VTAB_DIRECTONLY]]
    SQLITE_VTAB_DIRECTONLY
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** prohibits that virtual table from being used from within triggers and ** views. **
    @@ -9157,18 +9741,28 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. **
    +** +** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]
    SQLITE_VTAB_USES_ALL_SCHEMAS
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** instruct the query planner to begin at least a read transaction on +** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the +** virtual table is used. +**
    **
    */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS 2 #define SQLITE_VTAB_DIRECTONLY 3 +#define SQLITE_VTAB_USES_ALL_SCHEMAS 4 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy @@ -9186,10 +9780,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -** method of a [virtual table], then it returns true if and only if the +** method of a [virtual table], then it might return true if the ** column is being fetched as part of an UPDATE operation during which the -** column value will not change. Applications might use this to substitute -** a return value that is less expensive to compute and that the corresponding +** column value will not change. The virtual table implementation can use +** this hint as permission to substitute a return value that is less +** expensive to compute and that the corresponding ** [xUpdate] method understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that @@ -9198,23 +9793,285 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. +** +** The sqlite3_vtab_nochange() routine is an optimization. Virtual table +** implementations should continue to give a correct answer even if the +** sqlite3_vtab_nochange() interface were to always return false. In the +** current implementation, the sqlite3_vtab_nochange() interface does always +** returns false for the enhanced [UPDATE FROM] statement. */ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** METHOD: sqlite3_index_info ** ** This function may only be called from within a call to the [xBestIndex] -** method of a [virtual table]. +** method of a [virtual table]. This function returns a pointer to a string +** that is the name of the appropriate collation sequence to use for text +** comparisons on the constraint identified by its arguments. +** +** The first argument must be the pointer to the [sqlite3_index_info] object +** that is the first parameter to the xBestIndex() method. The second argument +** must be an index into the aConstraint[] array belonging to the +** sqlite3_index_info structure passed to xBestIndex. +** +** Important: +** The first parameter must be the same pointer that is passed into the +** xBestMethod() method. The first parameter may not be a pointer to a +** different [sqlite3_index_info] object, even an exact copy. +** +** The return value is computed as follows: +** +**
      +**
    1. If the constraint comes from a WHERE clause expression that contains +** a [COLLATE operator], then the name of the collation specified by +** that COLLATE operator is returned. +**

    2. If there is no COLLATE operator, but the column that is the subject +** of the constraint specifies an alternative collating sequence via +** a [COLLATE clause] on the column definition within the CREATE TABLE +** statement that was passed into [sqlite3_declare_vtab()], then the +** name of that alternative collating sequence is returned. +**

    3. Otherwise, "BINARY" is returned. +**

    +*/ +SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + +/* +** CAPI3REF: Determine if a virtual table query is DISTINCT +** METHOD: sqlite3_index_info +** +** This API may only be used from within an [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this +** interface from outside of xBestIndex() is undefined and probably harmful. +** +** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and +** 3. The integer returned by sqlite3_vtab_distinct() +** gives the virtual table additional information about how the query +** planner wants the output to be ordered. As long as the virtual table +** can meet the ordering requirements of the query planner, it may set +** the "orderByConsumed" flag. +** +**
    1. +** ^If the sqlite3_vtab_distinct() interface returns 0, that means +** that the query planner needs the virtual table to return all rows in the +** sort order defined by the "nOrderBy" and "aOrderBy" fields of the +** [sqlite3_index_info] object. This is the default expectation. If the +** virtual table outputs all rows in sorted order, then it is always safe for +** the xBestIndex method to set the "orderByConsumed" flag, regardless of +** the return value from sqlite3_vtab_distinct(). +**

    2. +** ^(If the sqlite3_vtab_distinct() interface returns 1, that means +** that the query planner does not need the rows to be returned in sorted order +** as long as all rows with the same values in all columns identified by the +** "aOrderBy" field are adjacent.)^ This mode is used when the query planner +** is doing a GROUP BY. +**

    3. +** ^(If the sqlite3_vtab_distinct() interface returns 2, that means +** that the query planner does not need the rows returned in any particular +** order, as long as rows with the same values in all "aOrderBy" columns +** are adjacent.)^ ^(Furthermore, only a single row for each particular +** combination of values in the columns identified by the "aOrderBy" field +** needs to be returned.)^ ^It is always ok for two or more rows with the same +** values in all "aOrderBy" columns to be returned, as long as all such rows +** are adjacent. ^The virtual table may, if it chooses, omit extra rows +** that have the same value for all columns identified by "aOrderBy". +** ^However omitting the extra rows is optional. +** This mode is used for a DISTINCT query. +**

    4. +** ^(If the sqlite3_vtab_distinct() interface returns 3, that means +** that the query planner needs only distinct rows but it does need the +** rows to be sorted.)^ ^The virtual table implementation is free to omit +** rows that are identical in all aOrderBy columns, if it wants to, but +** it is not required to omit any rows. This mode is used for queries +** that have both DISTINCT and ORDER BY clauses. +**

    +** +** ^For the purposes of comparing virtual table output values to see if the +** values are same value for sorting purposes, two NULL values are considered +** to be the same. In other words, the comparison operator is "IS" +** (or "IS NOT DISTINCT FROM") and not "==". +** +** If a virtual table implementation is unable to meet the requirements +** specified above, then it must not set the "orderByConsumed" flag in the +** [sqlite3_index_info] object or an incorrect answer may result. +** +** ^A virtual table implementation is always free to return rows in any order +** it wants, as long as the "orderByConsumed" flag is not set. ^When the +** the "orderByConsumed" flag is unset, the query planner will add extra +** [bytecode] to ensure that the final results returned by the SQL query are +** ordered correctly. The use of the "orderByConsumed" flag and the +** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful +** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" +** flag might help queries against a virtual table to run faster. Being +** overly aggressive and setting the "orderByConsumed" flag when it is not +** valid to do so, on the other hand, might cause SQLite to return incorrect +** results. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); + +/* +** CAPI3REF: Identify and handle IN constraints in xBestIndex +** +** This interface may only be used from within an +** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. +** The result of invoking this interface from any other context is +** undefined and probably harmful. +** +** ^(A constraint on a virtual table of the form +** "[IN operator|column IN (...)]" is +** communicated to the xBestIndex method as a +** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use +** this constraint, it must set the corresponding +** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under +** the usual mode of handling IN operators, SQLite generates [bytecode] +** that invokes the [xFilter|xFilter() method] once for each value +** on the right-hand side of the IN operator.)^ Thus the virtual table +** only sees a single value from the right-hand side of the IN operator +** at a time. +** +** In some cases, however, it would be advantageous for the virtual +** table to see all values on the right-hand of the IN operator all at +** once. The sqlite3_vtab_in() interfaces facilitates this in two ways: +** +**
      +**
    1. +** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) +** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint +** is an [IN operator] that can be processed all at once. ^In other words, +** sqlite3_vtab_in() with -1 in the third argument is a mechanism +** by which the virtual table can ask SQLite if all-at-once processing +** of the IN operator is even possible. +** +**

    2. +** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates +** to SQLite that the virtual table does or does not want to process +** the IN operator all-at-once, respectively. ^Thus when the third +** parameter (F) is non-negative, this interface is the mechanism by +** which the virtual table tells SQLite how it wants to process the +** IN operator. +**

    +** +** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times +** within the same xBestIndex method call. ^For any given P,N pair, +** the return value from sqlite3_vtab_in(P,N,F) will always be the same +** within the same xBestIndex call. ^If the interface returns true +** (non-zero), that means that the constraint is an IN operator +** that can be processed all-at-once. ^If the constraint is not an IN +** operator or cannot be processed all-at-once, then the interface returns +** false. +** +** ^(All-at-once processing of the IN operator is selected if both of the +** following conditions are met: +** +**
      +**
    1. The P->aConstraintUsage[N].argvIndex value is set to a positive +** integer. This is how the virtual table tells SQLite that it wants to +** use the N-th constraint. ** -** The first argument must be the sqlite3_index_info object that is the -** first parameter to the xBestIndex() method. The second argument must be -** an index into the aConstraint[] array belonging to the sqlite3_index_info -** structure passed to xBestIndex. This function returns a pointer to a buffer -** containing the name of the collation sequence for the corresponding -** constraint. +**

    2. The last call to sqlite3_vtab_in(P,N,F) for which F was +** non-negative had F>=1. +**

    )^ +** +** ^If either or both of the conditions above are false, then SQLite uses +** the traditional one-at-a-time processing strategy for the IN constraint. +** ^If both conditions are true, then the argvIndex-th parameter to the +** xFilter method will be an [sqlite3_value] that appears to be NULL, +** but which can be passed to [sqlite3_vtab_in_first()] and +** [sqlite3_vtab_in_next()] to find all values on the right-hand side +** of the IN constraint. */ -SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); + +/* +** CAPI3REF: Find all elements on the right-hand side of an IN constraint. +** +** These interfaces are only useful from within the +** [xFilter|xFilter() method] of a [virtual table] implementation. +** The result of invoking these interfaces from any other context +** is undefined and probably harmful. +** +** The X parameter in a call to sqlite3_vtab_in_first(X,P) or +** sqlite3_vtab_in_next(X,P) should be one of the parameters to the +** xFilter method which invokes these routines, and specifically +** a parameter that was previously selected for all-at-once IN constraint +** processing use the [sqlite3_vtab_in()] interface in the +** [xBestIndex|xBestIndex method]. ^(If the X parameter is not +** an xFilter argument that was selected for all-at-once IN constraint +** processing, then these routines return [SQLITE_ERROR].)^ +** +** ^(Use these routines to access all values on the right-hand side +** of the IN constraint using code like the following: +** +**
    +**    for(rc=sqlite3_vtab_in_first(pList, &pVal);
    +**        rc==SQLITE_OK && pVal;
    +**        rc=sqlite3_vtab_in_next(pList, &pVal)
    +**    ){
    +**      // do something with pVal
    +**    }
    +**    if( rc!=SQLITE_OK ){
    +**      // an error has occurred
    +**    }
    +** 
    )^ +** +** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) +** routines return SQLITE_OK and set *P to point to the first or next value +** on the RHS of the IN constraint. ^If there are no more values on the +** right hand side of the IN constraint, then *P is set to NULL and these +** routines return [SQLITE_DONE]. ^The return value might be +** some other value, such as SQLITE_NOMEM, in the event of a malfunction. +** +** The *ppOut values returned by these routines are only valid until the +** next call to either of these routines or until the end of the xFilter +** method from which these routines were called. If the virtual table +** implementation needs to retain the *ppOut values for longer, it must make +** copies. The *ppOut values are [protected sqlite3_value|protected]. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); + +/* +** CAPI3REF: Constraint values in xBestIndex() +** METHOD: sqlite3_index_info +** +** This API may only be used from within the [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this interface +** from outside of an xBestIndex method are undefined and probably harmful. +** +** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within +** the [xBestIndex] method of a [virtual table] implementation, with P being +** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and +** J being a 0-based index into P->aConstraint[], then this routine +** attempts to set *V to the value of the right-hand operand of +** that constraint if the right-hand operand is known. ^If the +** right-hand operand is not known, then *V is set to a NULL pointer. +** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th +** constraint is not available. ^The sqlite3_vtab_rhs_value() interface +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if +** something goes wrong. +** +** The sqlite3_vtab_rhs_value() interface is usually only successful if +** the right-hand operand of a constraint is a literal value in the original +** SQL statement. If the right-hand operand is an expression or a reference +** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() +** will probably return [SQLITE_NOTFOUND]. +** +** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and +** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such +** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ +** +** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value +** and remains valid for the duration of the xBestIndex method call. +** ^When xBestIndex returns, the sqlite3_value object returned by +** sqlite3_vtab_rhs_value() is automatically deallocated. +** +** The "_rhs_" in the name of this routine is an abbreviation for +** "Right-Hand Side". +*/ +SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); /* ** CAPI3REF: Conflict resolution modes @@ -9246,6 +10103,10 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_ ** managed by the prepared statement S and will be automatically freed when ** S is finalized. ** +** Not all values are available for all query elements. When a value is +** not available, the output variable is set to -1 if the value is numeric, +** or to NULL if it is a string (SQLITE_SCANSTAT_NAME). +** **
    ** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    **
    ^The [sqlite3_int64] variable pointed to by the V parameter will be @@ -9273,12 +10134,24 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_ ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] ** description for the X-th loop. ** -** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECT
    +** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECTID
    **
    ^The "int" variable pointed to by the V parameter will be set to the -** "select-id" for the X-th loop. The select-id identifies which query or -** subquery the loop is part of. The main query has a select-id of zero. -** The select-id is the same value as is output in the first column -** of an [EXPLAIN QUERY PLAN] query. +** id for the X-th query plan element. The id value is unique within the +** statement. The select-id is the same value as is output in the first +** column of an [EXPLAIN QUERY PLAN] query. +** +** [[SQLITE_SCANSTAT_PARENTID]]
    SQLITE_SCANSTAT_PARENTID
    +**
    The "int" variable pointed to by the V parameter will be set to the +** the id of the parent of the current query element, if applicable, or +** to zero if the query element has no parent. This is the same value as +** returned in the second column of an [EXPLAIN QUERY PLAN] query. +** +** [[SQLITE_SCANSTAT_NCYCLE]]
    SQLITE_SCANSTAT_NCYCLE
    +**
    The sqlite3_int64 output value is set to the number of cycles, +** according to the processor time-stamp counter, that elapsed while the +** query element was being processed. This value is not available for +** all query elements - if it is unavailable the output variable is +** set to -1. **
    */ #define SQLITE_SCANSTAT_NLOOP 0 @@ -9287,12 +10160,14 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_ #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 +#define SQLITE_SCANSTAT_PARENTID 6 +#define SQLITE_SCANSTAT_NCYCLE 7 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** -** This interface returns information about the predicted and measured +** These interfaces return information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. @@ -9303,19 +10178,25 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_ ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. -** ^The requested measurement is written into a variable pointed to by -** the "pOut" parameter. -** Parameter "idx" identifies the specific loop to retrieve statistics for. -** Loops are numbered starting from zero. ^If idx is out of range - less than -** zero or greater than or equal to the total number of loops used to implement -** the statement - a non-zero value is returned and the variable that pOut -** points to is unchanged. -** -** ^Statistics might not be available for all loops in all statements. ^In cases -** where there exist loops with no available statistics, this function behaves -** as if the loop did not exist - it returns non-zero and leave the variable -** that pOut points to unchanged. +** of this interface is undefined. ^The requested measurement is written into +** a variable pointed to by the "pOut" parameter. +** +** The "flags" parameter must be passed a mask of flags. At present only +** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX +** is specified, then status information is available for all elements +** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If +** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements +** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of +** the EXPLAIN QUERY PLAN output) are available. Invoking API +** sqlite3_stmt_scanstatus() is equivalent to calling +** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. +** +** Parameter "idx" identifies the specific query element to retrieve statistics +** for. Query elements are numbered starting from zero. A value of -1 may be +** to query for statistics regarding the entire query. ^If idx is out of range +** - less than -1 or greater than or equal to the total number of query +** elements used to implement the statement - a non-zero value is returned and +** the variable that pOut points to is unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ @@ -9324,7 +10205,20 @@ SQLITE_API int sqlite3_stmt_scanstatus( int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ -); +); +SQLITE_API int sqlite3_stmt_scanstatus_v2( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ + int flags, /* Mask of flags defined below */ + void *pOut /* Result written here */ +); + +/* +** CAPI3REF: Prepared Statement Scan Status +** KEYWORDS: {scan status flags} +*/ +#define SQLITE_SCANSTAT_COMPLEX 0x0001 /* ** CAPI3REF: Zero Scan-Status Counters @@ -9339,18 +10233,19 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction +** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty -** pages in the pager-cache that are not currently in use are written out +** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] ** interface flushes caches for all schemas - "main", "temp", and ** any [attached] databases. ** -** ^If this function needs to obtain extra database locks before dirty pages -** can be flushed to disk, it does so. ^If those locks cannot be obtained +** ^If this function needs to obtain extra database locks before dirty pages +** can be flushed to disk, it does so. ^If those locks cannot be obtained ** immediately and there is a busy-handler callback configured, it is invoked ** in the usual manner. ^If the required lock still cannot be obtained, then ** the database is skipped and an attempt made to flush any dirty pages @@ -9371,6 +10266,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. +** METHOD: sqlite3 ** ** ^These interfaces are only available if SQLite is compiled using the ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. @@ -9388,7 +10284,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ** ^The preupdate hook only fires for changes to real database tables; the ** preupdate hook is not invoked for changes to [virtual tables] or to -** system tables like sqlite_master or sqlite_stat1. +** system tables like sqlite_sequence or sqlite_stat1. ** ** ^The second parameter to the preupdate callback is a pointer to ** the [database connection] that registered the preupdate hook. @@ -9397,21 +10293,25 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** kind of update operation that is about to occur. ** ^(The fourth parameter to the preupdate callback is the name of the ** database within the database connection that is being modified. This -** will be "main" for the main database or "temp" for TEMP tables or +** will be "main" for the main database or "temp" for TEMP tables or ** the name given after the AS keyword in the [ATTACH] statement for attached ** databases.)^ ** ^The fifth parameter to the preupdate callback is the name of the ** table that is being modified. ** ** For an UPDATE or DELETE operation on a [rowid table], the sixth -** parameter passed to the preupdate callback is the initial [rowid] of the +** parameter passed to the preupdate callback is the initial [rowid] of the ** row being modified or deleted. For an INSERT operation on a rowid table, -** or any operation on a WITHOUT ROWID table, the value of the sixth +** or any operation on a WITHOUT ROWID table, the value of the sixth ** parameter is undefined. For an INSERT or UPDATE on a rowid table the ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for -** INSERT operations on rowid tables. +** DELETE operations on rowid tables. +** +** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from +** the previous call on the same [database connection] D, or NULL for +** the first call on D. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -9445,10 +10345,19 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** ** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete -** operation; or 1 for inserts, updates, or deletes invoked by top-level +** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** +** When the [sqlite3_blob_write()] API is used to update a blob column, +** the pre-update hook is invoked with SQLITE_DELETE. This is because the +** in this case the new values are not available. In this case, when a +** callback made with op==SQLITE_DELETE is actually a write using the +** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns +** the index of the column being written. In other cases, where the +** pre-update hook is being invoked for some other reason, including a +** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. +** ** See also: [sqlite3_update_hook()] */ #if defined(SQLITE_ENABLE_PREUPDATE_HOOK) @@ -9469,17 +10378,19 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); SQLITE_API int sqlite3_preupdate_count(sqlite3 *); SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); #endif /* ** CAPI3REF: Low-level system error code +** METHOD: sqlite3 ** ** ^Attempt to return the underlying operating system error code or error ** number that caused the most recent I/O error or failure to open a file. ** The return value is OS-dependent. For example, on unix systems, after ** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be ** called to get back the underlying "errno" that caused the problem, such -** as ENOSPC, EAUTH, EISDIR, and so forth. +** as ENOSPC, EAUTH, EISDIR, and so forth. */ SQLITE_API int sqlite3_system_errno(sqlite3*); @@ -9517,12 +10428,12 @@ typedef struct sqlite3_snapshot { ** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly ** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. ** If there is not already a read-transaction open on schema S when -** this function is called, one is opened automatically. +** this function is called, one is opened automatically. ** ** The following must be true for this function to succeed. If any of ** the following statements are false when sqlite3_snapshot_get() is ** called, SQLITE_ERROR is returned. The final value of *P is undefined -** in this case. +** in this case. ** ** ** ** This function may also return SQLITE_NOMEM. If it is called with the -** database handle in autocommit mode but fails for some other reason, +** database handle in autocommit mode but fails for some other reason, ** whether or not a read transaction is opened on schema S is undefined. ** ** The [sqlite3_snapshot] object returned from a successful call to @@ -9560,38 +10471,38 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( ** CAPI3REF: Start a read transaction on an historical snapshot ** METHOD: sqlite3_snapshot ** -** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read -** transaction or upgrades an existing one for schema S of -** [database connection] D such that the read transaction refers to -** historical [snapshot] P, rather than the most recent change to the -** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read +** transaction or upgrades an existing one for schema S of +** [database connection] D such that the read transaction refers to +** historical [snapshot] P, rather than the most recent change to the +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK ** on success or an appropriate [error code] if it fails. ** -** ^In order to succeed, the database connection must not be in +** ^In order to succeed, the database connection must not be in ** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there ** is already a read transaction open on schema S, then the database handle ** must have no active statements (SELECT statements that have been passed -** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). ** SQLITE_ERROR is returned if either of these conditions is violated, or ** if schema S does not exist, or if the snapshot object is invalid. ** ** ^A call to sqlite3_snapshot_open() will fail to open if the specified -** snapshot has been overwritten by a [checkpoint]. In this case +** snapshot has been overwritten by a [checkpoint]. In this case ** SQLITE_ERROR_SNAPSHOT is returned. ** -** If there is already a read transaction open when this function is +** If there is already a read transaction open when this function is ** invoked, then the same read transaction remains open (on the same ** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT ** is returned. If another error code - for example SQLITE_PROTOCOL or an ** SQLITE_IOERR error code - is returned, then the final state of the -** read transaction is undefined. If SQLITE_OK is returned, then the +** read transaction is undefined. If SQLITE_OK is returned, then the ** read transaction is now open on database snapshot P. ** ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for ** schema S is in [WAL mode]. A database connection might not know ** that the database file is in [WAL mode] if there has been no prior -** I/O on that database connection, or if the database entered [WAL mode] +** I/O on that database connection, or if the database entered [WAL mode] ** after the most recent I/O on the database connection.)^ ** (Hint: Run "[PRAGMA application_id]" against a newly opened ** database connection in order to make it ready to use snapshots.) @@ -9623,17 +10534,17 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); ** METHOD: sqlite3_snapshot ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages -** of two valid snapshot handles. +** of two valid snapshot handles. ** -** If the two snapshot handles are not associated with the same database -** file, the result of the comparison is undefined. +** If the two snapshot handles are not associated with the same database +** file, the result of the comparison is undefined. ** ** Additionally, the result of the comparison is only valid if both of the ** snapshot handles were obtained by calling sqlite3_snapshot_get() since the ** last time the wal file was deleted. The wal file is deleted when the ** database is changed back to rollback mode or when the number of database -** clients drops to zero. If either snapshot handle was obtained before the -** wal file was last deleted, the value returned by this function +** clients drops to zero. If either snapshot handle was obtained before the +** wal file was last deleted, the value returned by this function ** is undefined. ** ** Otherwise, this API returns a negative value if P1 refers to an older @@ -9698,16 +10609,23 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same ** values of D and S. -** The size of the database is written into *P even if the +** The size of the database is written into *P even if the ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** +** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, +** the returned buffer content will remain accessible and unchanged +** until either the next write operation on the connection or when +** the connection is closed, and applications must not modify the +** buffer. If the bit had been clear, the returned buffer will not +** be accessed by SQLite after the call. +** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. ** -** This interface is only available if SQLite is compiled with the -** [SQLITE_ENABLE_DESERIALIZE] option. +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API unsigned char *sqlite3_serialize( sqlite3 *db, /* The database connection */ @@ -9735,7 +10653,7 @@ SQLITE_API unsigned char *sqlite3_serialize( /* ** CAPI3REF: Deserialize a database ** -** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the +** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the ** [database connection] D to disconnect from database S and then ** reopen S as an in-memory database based on the serialization contained ** in P. The serialized database P is N bytes in size. M is the size of @@ -9750,16 +10668,30 @@ SQLITE_API unsigned char *sqlite3_serialize( ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** +** Applications must not modify the buffer P or invalidate it before +** the database connection D is closed. +** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. ** -** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the +** It is not possible to deserialized into the TEMP database. If the +** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the +** function returns SQLITE_ERROR. +** +** The deserialized database should not be in [WAL mode]. If the database +** is in WAL mode, then any attempt to use the database file will result +** in an [SQLITE_CANTOPEN] error. The application can set the +** [file format version numbers] (bytes 18 and 19) of the input database P +** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the +** database file into rollback mode and work around this limitation. +** +** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. ** -** This interface is only available if SQLite is compiled with the -** [SQLITE_ENABLE_DESERIALIZE] option. +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ @@ -9803,6 +10735,19 @@ SQLITE_API int sqlite3_deserialize( # undef double #endif +#if defined(__wasi__) +# undef SQLITE_WASI +# define SQLITE_WASI 1 +# undef SQLITE_OMIT_WAL +# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ +# ifndef SQLITE_OMIT_LOAD_EXTENSION +# define SQLITE_OMIT_LOAD_EXTENSION +# endif +# ifndef SQLITE_THREADSAFE +# define SQLITE_THREADSAFE 0 +# endif +#endif + #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif @@ -9869,7 +10814,7 @@ struct sqlite3_rtree_geometry { }; /* -** Register a 2nd-generation geometry callback named zScore that can be +** Register a 2nd-generation geometry callback named zScore that can be ** used as part of an R-Tree geometry query as follows: ** ** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) @@ -9884,7 +10829,7 @@ SQLITE_API int sqlite3_rtree_query_callback( /* -** A pointer to a structure of the following type is passed as the +** A pointer to a structure of the following type is passed as the ** argument to scored geometry callback registered using ** sqlite3_rtree_query_callback(). ** @@ -9979,7 +10924,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; ** is not possible for an application to register a pre-update hook on a ** database handle that has one or more session objects attached. Nor is ** it possible to create a session object attached to a database handle for -** which a pre-update hook is already defined. The results of attempting +** which a pre-update hook is already defined. The results of attempting ** either of these things are undefined. ** ** The session object will be used to create changesets for tables in @@ -9997,17 +10942,62 @@ SQLITE_API int sqlite3session_create( ** CAPI3REF: Delete A Session Object ** DESTRUCTOR: sqlite3_session ** -** Delete a session object previously allocated using +** Delete a session object previously allocated using ** [sqlite3session_create()]. Once a session object has been deleted, the ** results of attempting to use pSession with any other session module ** function are undefined. ** ** Session objects must be deleted before the database handle to which they -** are attached is closed. Refer to the documentation for +** are attached is closed. Refer to the documentation for ** [sqlite3session_create()] for details. */ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); +/* +** CAPI3REF: Configure a Session Object +** METHOD: sqlite3_session +** +** This method is used to configure a session object after it has been +** created. At present the only valid values for the second parameter are +** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID]. +** +*/ +SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +** CAPI3REF: Options for sqlite3session_object_config +** +** The following values may passed as the the 2nd parameter to +** sqlite3session_object_config(). +** +**
    SQLITE_SESSION_OBJCONFIG_SIZE
    +** This option is used to set, clear or query the flag that enables +** the [sqlite3session_changeset_size()] API. Because it imposes some +** computational overhead, this API is disabled by default. Argument +** pArg must point to a value of type (int). If the value is initially +** 0, then the sqlite3session_changeset_size() API is disabled. If it +** is greater than 0, then the same API is enabled. Or, if the initial +** value is less than zero, no change is made. In all cases the (int) +** variable is set to 1 if the sqlite3session_changeset_size() API is +** enabled following the current call, or 0 otherwise. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +** +**
    SQLITE_SESSION_OBJCONFIG_ROWID
    +** This option is used to set, clear or query the flag that enables +** collection of data for tables with no explicit PRIMARY KEY. +** +** Normally, tables with no explicit PRIMARY KEY are simply ignored +** by the sessions module. However, if this flag is set, it behaves +** as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted +** as their leftmost columns. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 +#define SQLITE_SESSION_OBJCONFIG_ROWID 2 /* ** CAPI3REF: Enable Or Disable A Session Object @@ -10021,10 +11011,10 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); ** the eventual changesets. ** ** Passing zero to this function disables the session. Passing a value -** greater than zero enables it. Passing a value less than zero is a +** greater than zero enables it. Passing a value less than zero is a ** no-op, and may be used to query the current state of the session. ** -** The return value indicates the final state of the session object: 0 if +** The return value indicates the final state of the session object: 0 if ** the session is disabled, or 1 if it is enabled. */ SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); @@ -10039,7 +11029,7 @@ SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); ** ** @@ -10051,10 +11041,10 @@ SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); ** flag. If the second argument passed to this function is zero, then the ** indirect flag is cleared. If it is greater than zero, the indirect flag ** is set. Passing a value less than zero does not modify the current value -** of the indirect flag, and may be used to query the current state of the +** of the indirect flag, and may be used to query the current state of the ** indirect flag for the specified session object. ** -** The return value indicates the final state of the indirect flag: 0 if +** The return value indicates the final state of the indirect flag: 0 if ** it is clear, or 1 if it is set. */ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); @@ -10064,20 +11054,20 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect) ** METHOD: sqlite3_session ** ** If argument zTab is not NULL, then it is the name of a table to attach -** to the session object passed as the first argument. All subsequent changes -** made to the table while the session object is enabled will be recorded. See +** to the session object passed as the first argument. All subsequent changes +** made to the table while the session object is enabled will be recorded. See ** documentation for [sqlite3session_changeset()] for further details. ** ** Or, if argument zTab is NULL, then changes are recorded for all tables -** in the database. If additional tables are added to the database (by -** executing "CREATE TABLE" statements) after this call is made, changes for +** in the database. If additional tables are added to the database (by +** executing "CREATE TABLE" statements) after this call is made, changes for ** the new tables are also recorded. ** ** Changes can only be recorded for tables that have a PRIMARY KEY explicitly -** defined as part of their CREATE TABLE statement. It does not matter if the +** defined as part of their CREATE TABLE statement. It does not matter if the ** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY ** KEY may consist of a single column, or may be a composite key. -** +** ** It is not an error if the named table does not exist in the database. Nor ** is it an error if the named table does not have a PRIMARY KEY. However, ** no changes will be recorded in either of these scenarios. @@ -10085,29 +11075,29 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect) ** Changes are not recorded for individual rows that have NULL values stored ** in one or more of their PRIMARY KEY columns. ** -** SQLITE_OK is returned if the call completes without error. Or, if an error +** SQLITE_OK is returned if the call completes without error. Or, if an error ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. ** **

    Special sqlite_stat1 Handling

    ** -** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to +** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to ** some of the rules above. In SQLite, the schema of sqlite_stat1 is: **
    -**        CREATE TABLE sqlite_stat1(tbl,idx,stat)  
    +**        CREATE TABLE sqlite_stat1(tbl,idx,stat)
     **  
    ** -** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are -** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes +** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are +** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes ** are recorded for rows for which (idx IS NULL) is true. However, for such ** rows a zero-length blob (SQL value X'') is stored in the changeset or ** patchset instead of a NULL value. This allows such changesets to be ** manipulated by legacy implementations of sqlite3changeset_invert(), ** concat() and similar. ** -** The sqlite3changeset_apply() function automatically converts the +** The sqlite3changeset_apply() function automatically converts the ** zero-length blob back to a NULL value when updating the sqlite_stat1 ** table. However, if the application calls sqlite3changeset_new(), -** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset +** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset ** iterator directly (including on a changeset iterator passed to a ** conflict-handler callback) then the X'' value is returned. The application ** must translate X'' to NULL itself if required. @@ -10126,10 +11116,10 @@ SQLITE_API int sqlite3session_attach( ** CAPI3REF: Set a table filter on a Session Object. ** METHOD: sqlite3_session ** -** The second argument (xFilter) is the "filter callback". For changes to rows +** The second argument (xFilter) is the "filter callback". For changes to rows ** in tables that are not attached to the Session object, the filter is called -** to determine whether changes to the table's rows should be tracked or not. -** If xFilter returns 0, changes are not tracked. Note that once a table is +** to determine whether changes to the table's rows should be tracked or not. +** If xFilter returns 0, changes are not tracked. Note that once a table is ** attached, xFilter will not be called again. */ SQLITE_API void sqlite3session_table_filter( @@ -10145,9 +11135,9 @@ SQLITE_API void sqlite3session_table_filter( ** CAPI3REF: Generate A Changeset From A Session Object ** METHOD: sqlite3_session ** -** Obtain a changeset containing changes to the tables attached to the -** session object passed as the first argument. If successful, -** set *ppChangeset to point to a buffer containing the changeset +** Obtain a changeset containing changes to the tables attached to the +** session object passed as the first argument. If successful, +** set *ppChangeset to point to a buffer containing the changeset ** and *pnChangeset to the size of the changeset in bytes before returning ** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to ** zero and return an SQLite error code. @@ -10162,7 +11152,7 @@ SQLITE_API void sqlite3session_table_filter( ** modifies the values of primary key columns. If such a change is made, it ** is represented in a changeset as a DELETE followed by an INSERT. ** -** Changes are not recorded for rows that have NULL values stored in one or +** Changes are not recorded for rows that have NULL values stored in one or ** more of their PRIMARY KEY columns. If such a row is inserted or deleted, ** no corresponding change is present in the changesets returned by this ** function. If an existing row with one or more NULL values stored in @@ -10215,14 +11205,14 @@ SQLITE_API void sqlite3session_table_filter( ** ** ** For each token in the input string, the supplied callback xToken() must @@ -11966,10 +13055,10 @@ struct Fts5ExtensionApi { ** which the token is derived within the input. ** ** The second argument passed to the xToken() callback ("tflags") should -** normally be set to 0. The exception is if the tokenizer supports +** normally be set to 0. The exception is if the tokenizer supports ** synonyms. In this case see the discussion below for details. ** -** FTS5 assumes the xToken() callback is invoked for each token in the +** FTS5 assumes the xToken() callback is invoked for each token in the ** order that they occur within the input text. ** ** If an xToken() callback returns any value other than SQLITE_OK, then @@ -11983,7 +13072,7 @@ struct Fts5ExtensionApi { ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a -** user wishes to query for a phrase such as "first place". Using the +** user wishes to query for a phrase such as "first place". Using the ** built-in tokenizers, the FTS5 query 'first + place' will match instances ** of "first place" within the document set, but not alternative forms ** such as "1st place". In some applications, it would be better to match @@ -12003,34 +13092,34 @@ struct Fts5ExtensionApi { ** **
  • By querying the index for all synonyms of each query term ** separately. In this case, when tokenizing query text, the -** tokenizer may provide multiple synonyms for a single term -** within the document. FTS5 then queries the index for each +** tokenizer may provide multiple synonyms for a single term +** within the document. FTS5 then queries the index for each ** synonym individually. For example, faced with the query: ** ** ** ... MATCH 'first place' ** ** the tokenizer offers both "1st" and "first" as synonyms for the -** first token in the MATCH query and FTS5 effectively runs a query +** first token in the MATCH query and FTS5 effectively runs a query ** similar to: ** ** ** ... MATCH '(first OR 1st) place' ** ** except that, for the purposes of auxiliary functions, the query -** still appears to contain just two phrases - "(first OR 1st)" +** still appears to contain just two phrases - "(first OR 1st)" ** being treated as a single phrase. ** **
  • By adding multiple synonyms for a single term to the FTS index. ** Using this method, when tokenizing document text, the tokenizer -** provides multiple synonyms for each token. So that when a +** provides multiple synonyms for each token. So that when a ** document such as "I won first place" is tokenized, entries are ** added to the FTS index for "i", "won", "first", "1st" and ** "place". ** ** This way, even if the tokenizer does not provide synonyms ** when tokenizing query text (it should not - to do so would be -** inefficient), it doesn't matter if the user queries for +** inefficient), it doesn't matter if the user queries for ** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. ** @@ -12051,11 +13140,11 @@ struct Fts5ExtensionApi { ** ** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time ** xToken() is called. Multiple synonyms may be specified for a single token -** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. +** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. ** There is no limit to the number of synonyms that may be provided for a ** single token. ** -** In many cases, method (1) above is the best approach. It does not add +** In many cases, method (1) above is the best approach. It does not add ** extra data to the FTS index or require FTS5 to query for multiple terms, ** so it is efficient in terms of disk space and query speed. However, it ** does not support prefix queries very well. If, as suggested above, the @@ -12067,24 +13156,24 @@ struct Fts5ExtensionApi { ** will not match documents that contain the token "1st" (as the tokenizer ** will probably not map "1s" to any prefix of "first"). ** -** For full prefix support, method (3) may be preferred. In this case, +** For full prefix support, method (3) may be preferred. In this case, ** because the index contains entries for both "first" and "1st", prefix ** queries such as 'fi*' or '1s*' will match correctly. However, because ** extra entries are added to the FTS index, this method uses more space ** within the database. ** ** Method (2) offers a midpoint between (1) and (3). Using this method, -** a query such as '1s*' will match documents that contain the literal +** a query such as '1s*' will match documents that contain the literal ** token "1st", but not "first" (assuming the tokenizer is not able to ** provide synonyms for prefixes). However, a non-prefix query like '1st' ** will match against "1st" and "first". This method does not require -** extra disk space, as no extra entries are added to the FTS index. +** extra disk space, as no extra entries are added to the FTS index. ** On the other hand, it may require more CPU cycles to run MATCH queries, ** as separate queries of the FTS index are required for each synonym. ** ** When using methods (2) or (3), it is important that the tokenizer only -** provide synonyms when tokenizing document text (method (2)) or query -** text (method (3)), not both. Doing so will not cause any errors, but is +** provide synonyms when tokenizing document text (method (3)) or query +** text (method (2)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; @@ -12092,10 +13181,10 @@ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); void (*xDelete)(Fts5Tokenizer*); - int (*xTokenize)(Fts5Tokenizer*, + int (*xTokenize)(Fts5Tokenizer*, void *pCtx, int flags, /* Mask of FTS5_TOKENIZE_* flags */ - const char *pText, int nText, + const char *pText, int nText, int (*xToken)( void *pCtx, /* Copy of 2nd argument to xTokenize() */ int tflags, /* Mask of FTS5_TOKEN_* flags */ @@ -12132,7 +13221,7 @@ struct fts5_api { int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, - void *pContext, + void *pUserData, fts5_tokenizer *pTokenizer, void (*xDestroy)(void*) ); @@ -12141,7 +13230,7 @@ struct fts5_api { int (*xFindTokenizer)( fts5_api *pApi, const char *zName, - void **ppContext, + void **ppUserData, fts5_tokenizer *pTokenizer ); @@ -12149,7 +13238,7 @@ struct fts5_api { int (*xCreateFunction)( fts5_api *pApi, const char *zName, - void *pContext, + void *pUserData, fts5_extension_function xFunction, void (*xDestroy)(void*) ); diff --git a/pom.xml b/pom.xml index 530aa6569..fed3ab079 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ github.fileengine File-Engine - 4.3 + 4.4 mulesoft @@ -94,12 +94,12 @@ org.xerial sqlite-jdbc - 3.43.0.0 + 3.44.0.0 com.formdev flatlaf - 3.2.1 + 3.2.5 @@ -110,7 +110,7 @@ com.formdev flatlaf-intellij-themes - 3.2.1 + 3.2.5 io.github.biezhi diff --git a/src/main/resources/win32-native/sqlite3.dll b/src/main/resources/win32-native/sqlite3.dll index 9fc8176c9..1239c3520 100644 Binary files a/src/main/resources/win32-native/sqlite3.dll and b/src/main/resources/win32-native/sqlite3.dll differ diff --git a/src/main/resources/win32-native/sqliteJDBC.dll b/src/main/resources/win32-native/sqliteJDBC.dll index 22d8adbf0..5b0f195bb 100644 Binary files a/src/main/resources/win32-native/sqliteJDBC.dll and b/src/main/resources/win32-native/sqliteJDBC.dll differ