mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
vcs log sqlite backend - rename native lib to avoid conflicts
GitOrigin-RevId: 242c92aef577c49598355a87d5597ee85642d2ea
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6ba8d7ec6b
commit
2b6c42bbb1
4
.idea/libraries/sqlite_native.xml
generated
4
.idea/libraries/sqlite_native.xml
generated
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="sqlite-native" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.sqlite:native:3.40.0-2" />
|
||||
<properties include-transitive-deps="false" maven-id="org.sqlite:native:3.40.0-11" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/sqlite/native/3.40.0-2/native-3.40.0-2.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/sqlite/native/3.40.0-11/native-3.40.0-11.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
@@ -509,18 +509,27 @@ private suspend fun unpackNativeLibraries(sourceFile: Path, paths: List<String>,
|
||||
val libVersion = sourceFile.getName(sourceFile.nameCount - 2).toString()
|
||||
val signTool = context.proprietaryBuildTools.signTool
|
||||
val unsignedFiles = TreeMap<OsFamily, MutableList<Path>>()
|
||||
val packagePrefix = getCommonPath(paths)
|
||||
|
||||
val packagePrefix = if (paths.size == 1) {
|
||||
// if a native lib is built with the only arch for testing purposes
|
||||
val first = paths.first()
|
||||
first.substring(0, first.indexOf('/') + 1)
|
||||
}
|
||||
else {
|
||||
getCommonPath(paths)
|
||||
}
|
||||
|
||||
val libName = sourceFile.name.substringBefore('-')
|
||||
HashMapZipFile.load(sourceFile).use { zipFile ->
|
||||
val jnaOutDir = Files.createDirectories(context.paths.tempDir.resolve(libName))
|
||||
Files.createDirectories(jnaOutDir)
|
||||
val outDir = Files.createDirectories(context.paths.tempDir.resolve(libName))
|
||||
Files.createDirectories(outDir)
|
||||
for (pathWithPackage in paths) {
|
||||
val path = pathWithPackage.substring(packagePrefix.length)
|
||||
val fileName = path.substring(path.lastIndexOf('/') + 1)
|
||||
|
||||
val os = when {
|
||||
path.startsWith("darwin-") || path.startsWith("darwin/") || path.startsWith("mac/") || path.startsWith("Mac/") -> OsFamily.MACOS
|
||||
path.startsWith("win32-") || path.startsWith("win/") || path.startsWith("Windows/") -> OsFamily.WINDOWS
|
||||
path.startsWith("darwin-") || path.startsWith("mac-") || path.startsWith("darwin/") || path.startsWith("mac/") || path.startsWith("Mac/") -> OsFamily.MACOS
|
||||
path.startsWith("win32-") || path.startsWith("win/") || path.startsWith("win-") || path.startsWith("Windows/") -> OsFamily.WINDOWS
|
||||
path.startsWith("Linux-Android/") || path.startsWith("Linux-Musl/") -> continue
|
||||
path.startsWith("linux-") || path.startsWith("linux/") || path.startsWith("Linux/") -> OsFamily.LINUX
|
||||
else -> continue
|
||||
@@ -529,7 +538,7 @@ private suspend fun unpackNativeLibraries(sourceFile: Path, paths: List<String>,
|
||||
val osAndArch = path.substring(0, path.indexOf('/'))
|
||||
val arch: JvmArchitecture? = when {
|
||||
osAndArch.endsWith("-aarch64") || path.contains("/aarch64/") -> JvmArchitecture.aarch64
|
||||
osAndArch.endsWith("-x86-64") || path.contains("/x86-64/") || path.contains("/x86_64/") -> JvmArchitecture.x64
|
||||
osAndArch.contains("x86-64") || path.contains("x86_64") -> JvmArchitecture.x64
|
||||
// universal library
|
||||
os == OsFamily.MACOS && path.count { it == '/' } == 1 -> null
|
||||
else -> continue
|
||||
@@ -544,7 +553,7 @@ private suspend fun unpackNativeLibraries(sourceFile: Path, paths: List<String>,
|
||||
|
||||
if (file == null) {
|
||||
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
|
||||
file = jnaOutDir.resolve(path)!!
|
||||
file = outDir.resolve(path)!!
|
||||
Files.createDirectories(file.parent)
|
||||
FileChannel.open(file, W_CREATE_NEW).use { channel ->
|
||||
val byteBuffer = zipFile.getByteBuffer(pathWithPackage)!!
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("ReplaceGetOrSet")
|
||||
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
// https://rosettacode.org/wiki/Find_common_directory_path#Java
|
||||
fun getCommonPath(paths: List<String>): String {
|
||||
internal fun getCommonPath(paths: List<String>): String {
|
||||
var commonPath = ""
|
||||
val folders = Array(paths.size) { paths[it].split('/') }
|
||||
for (j in folders[0].indices) {
|
||||
|
||||
1
platform/sqlite/.gitignore
vendored
Normal file
1
platform/sqlite/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target/
|
||||
22
platform/sqlite/Makefile
Normal file
22
platform/sqlite/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
.phony: archive-native install-native
|
||||
|
||||
archive-native:
|
||||
rm -f target/sqlite-native.jar
|
||||
cd target && zip -r sqlite-native.jar sqlite -i '*.jnilib' '*.so' '*.dll' '*.sha256'
|
||||
|
||||
install-native: archive-native
|
||||
mvn install:install-file -DgroupId=org.sqlite \
|
||||
-DartifactId=native \
|
||||
-Dversion=3.40.0-11 \
|
||||
-Dpackaging=jar \
|
||||
-Dfile=target/sqlite-native.jar
|
||||
|
||||
deploy-native: archive-native
|
||||
mvn deploy:deploy-file -DgroupId=org.sqlite \
|
||||
-DartifactId=native \
|
||||
-Dversion=3.40.0-11 \
|
||||
-Dpackaging=jar \
|
||||
-Dfile=target/sqlite-native.jar \
|
||||
-DrepositoryId=space-intellij-dependencies \
|
||||
-Durl=https://packages.jetbrains.team/maven/p/ij/intellij-dependencies
|
||||
49
platform/sqlite/build.sh
Executable file
49
platform/sqlite/build.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
set -ex
|
||||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
createSysRoot() {
|
||||
outDir="target/linux-$1"
|
||||
if [ -d "$outDir" ]; then
|
||||
echo "Sysroot $outDir exists, skip creating"
|
||||
return
|
||||
fi
|
||||
|
||||
imageArch=""
|
||||
if [ "$1" == "x86_64" ]; then
|
||||
imageArch=amd64
|
||||
elif [ "$1" == "aarch64" ]; then
|
||||
imageArch=arm64v8
|
||||
fi
|
||||
|
||||
mkdir -p "$outDir"
|
||||
# use old glibc (2.24)
|
||||
nerdctl save --platform linux/$imageArch -o "$outDir.tar" buildpack-deps:bionic
|
||||
python3 docker-image-extract.py "$outDir.tar" "$outDir"
|
||||
unlink "$outDir.tar"
|
||||
}
|
||||
|
||||
createSysRoot x86_64
|
||||
#createSysRoot aarch64
|
||||
|
||||
# echo "deb http://archive.ubuntu.com/ubuntu/ jammy-proposed universe" | tee /etc/apt/sources.list.d/docker.list
|
||||
|
||||
# apt-get update && apt install -y install clang lldb lld
|
||||
#nerdctl run -ti -v "$SCRIPT_DIR":/work silkeh/clang@sha256:693fdfa16424b2f41408204933b63a796e2700f1865a19c7eec7f6606040d7fd
|
||||
|
||||
#OS=mac ARCH=aarch64 ./make.sh
|
||||
#OS=mac ARCH=x86_64 ./make.sh
|
||||
#OS=linux ARCH=aarch64 ./make.sh
|
||||
#OS=linux ARCH=x86_64 ./make.sh
|
||||
#
|
||||
#nerdctl run --rm --platform linux/amd64 -v "$SCRIPT_DIR":/work --workdir=/work \
|
||||
# dockcross/windows-static-x64 bash -c 'OS=win ARCH=x86_64 CC=gcc CROSS_PREFIX=x86_64-w64-mingw32.static- ./make.sh'
|
||||
#
|
||||
#nerdctl run --rm --platform linux/amd64 -v "$SCRIPT_DIR":/work --workdir=/work \
|
||||
# dockcross/windows-arm64 bash -c 'OS=win ARCH=aarch64 CC=clang CROSS_PREFIX=aarch64-w64-mingw32- ./make.sh'
|
||||
|
||||
nerdctl run --rm --platform linux/amd64 -v "$SCRIPT_DIR":/work --workdir=/work \
|
||||
dockcross/linux-arm64 bash -c 'OS=linux ARCH=aarch64 CC=gcc CROSS_PREFIX=aarch64-unknown-linux-gnu- ./make.sh'
|
||||
32
platform/sqlite/docker-image-extract.py
Normal file
32
platform/sqlite/docker-image-extract.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# https://www.madebymikal.com/quick-hack-extracting-the-contents-of-a-docker-image-to-disk/
|
||||
|
||||
# Call me like this:
|
||||
# docker-image-extract tarfile.tar extracted
|
||||
|
||||
import tarfile
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
image_path = sys.argv[1]
|
||||
extracted_path = sys.argv[2]
|
||||
|
||||
image = tarfile.open(image_path)
|
||||
manifest = json.loads(image.extractfile('manifest.json').read())
|
||||
|
||||
for layer in manifest[0]['Layers']:
|
||||
print('Found layer: %s' % layer)
|
||||
layer_tar = tarfile.open(fileobj=image.extractfile(layer))
|
||||
|
||||
for tarinfo in layer_tar:
|
||||
print(' ... %s' % tarinfo.name)
|
||||
if tarinfo.isdev():
|
||||
print(' --> skip device files')
|
||||
continue
|
||||
|
||||
dest = os.path.join(extracted_path, tarinfo.name)
|
||||
if not tarinfo.isdir() and os.path.exists(dest):
|
||||
print(' --> remove old version of file')
|
||||
os.unlink(dest)
|
||||
|
||||
layer_tar.extract(tarinfo, path=extracted_path)
|
||||
@@ -5,6 +5,8 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/sqlite" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
||||
76
platform/sqlite/make.sh
Executable file
76
platform/sqlite/make.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
set -ex
|
||||
|
||||
outDir="target/sqlite/$OS-$ARCH"
|
||||
rm -rf "${outDir:?}/*"
|
||||
mkdir -p "$outDir"
|
||||
|
||||
# brew install llvm
|
||||
# use latest CLang 15 instead of 14 for a smaller binaries
|
||||
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
|
||||
export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
|
||||
export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
|
||||
|
||||
cFlags="-O3 -fPIC -Isqlite -fvisibility=hidden -Wno-implicit-function-declaration"
|
||||
linkFlags="-Wl,-S,-x"
|
||||
libFilename="so"
|
||||
if [ "$OS" == "mac" ]; then
|
||||
cFlags+=" -mmacosx-version-min=10.14"
|
||||
linkFlags="-dynamiclib -fuse-ld=lld "
|
||||
libFilename="libsqliteij.jnilib"
|
||||
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
cFlags+=" --target=x86_64-apple-darwin18.7.0"
|
||||
fi
|
||||
elif [ "$OS" == "linux" ]; then
|
||||
libFilename="libsqliteij.so"
|
||||
|
||||
# cannot compile arm - unable to find library -lgcc, so, use dock cross
|
||||
if [ "$ARCH" == "aarch64" ]; then
|
||||
linkFlags+=" -shared"
|
||||
else
|
||||
cFlags+=" --target=$ARCH-unknown-linux-gnu --sysroot=target/linux-$ARCH"
|
||||
linkFlags+=" -shared -fuse-ld=lld"
|
||||
fi
|
||||
elif [ "$OS" == "win" ]; then
|
||||
linkFlags="-Wl,--kill-at -shared -static-libgcc"
|
||||
libFilename="sqliteij.dll"
|
||||
fi
|
||||
|
||||
CC="${CC:-clang}"
|
||||
|
||||
#linkFlags+=" -fuse-ld=lld"
|
||||
"${CROSS_PREFIX}${CC}" -o "$outDir/sqlite3.o" -c $cFlags \
|
||||
-DSQLITE_DQS=1 \
|
||||
-DSQLITE_THREADSAFE=1 \
|
||||
-DSQLITE_DEFAULT_MEMSTATUS=0 \
|
||||
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
|
||||
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
|
||||
-DSQLITE_MAX_EXPR_DEPTH=0 \
|
||||
-DSQLITE_OMIT_DECLTYPE \
|
||||
-DSQLITE_OMIT_DEPRECATED \
|
||||
-DSQLITE_OMIT_PROGRESS_CALLBACK \
|
||||
-DSQLITE_OMIT_SHARED_CACHE \
|
||||
-DSQLITE_USE_ALLOCA \
|
||||
-DSQLITE_OMIT_AUTOINIT \
|
||||
-DSQLITE_HAVE_ISNAN \
|
||||
-DHAVE_USLEEP=1 \
|
||||
-DSQLITE_TEMP_STORE=2 \
|
||||
-DSQLITE_DEFAULT_CACHE_SIZE=2000 \
|
||||
-DSQLITE_CORE \
|
||||
-DSQLITE_ENABLE_FTS5 \
|
||||
-DSQLITE_ENABLE_RTREE \
|
||||
-DSQLITE_ENABLE_STAT4 \
|
||||
-DSQLITE_MAX_MMAP_SIZE=1099511627776 \
|
||||
\
|
||||
sqlite/sqlite3.c
|
||||
|
||||
"${CROSS_PREFIX}${CC}" -o "$outDir/NativeDB.o" -c $cFlags -I"sqlite/$OS" sqlite/NativeDB.c
|
||||
|
||||
libFile="$outDir/$libFilename"
|
||||
"${CROSS_PREFIX}${CC}" $cFlags -o "$libFile" "$outDir/NativeDB.o" "$outDir/sqlite3.o" $linkFlags
|
||||
shasum -a 256 "$libFile" | head -c 64 >"$libFile.sha256"
|
||||
|
||||
unlink "$outDir/sqlite3.o"
|
||||
unlink "$outDir/NativeDB.o"
|
||||
@@ -53,7 +53,7 @@ static jmethodID w_mth_inverse = 0;
|
||||
static jmethodID w_mth_xvalue = 0;
|
||||
|
||||
static jclass pclass = 0;
|
||||
static jclass phandleclass = 0;
|
||||
//static jclass phandleclass = 0;
|
||||
static jmethodID pmethod = 0;
|
||||
|
||||
static jmethodID exp_msg = 0;
|
||||
@@ -427,11 +427,15 @@ 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;
|
||||
if (JNI_OK != (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2)) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
dbclass = (*env)->FindClass(env, "org/jetbrains/sqlite/NativeDB");
|
||||
if (!dbclass) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
dbclass = (*env)->FindClass(env, "org/jetbrains/sqlite/core/NativeDB");
|
||||
if (!dbclass) return JNI_ERR;
|
||||
dbclass = (*env)->NewWeakGlobalRef(env, dbclass);
|
||||
dbpointer = (*env)->GetFieldID(env, dbclass, "pointer", "J");
|
||||
mth_stringToUtf8ByteArray = (*env)->GetStaticMethodID(
|
||||
@@ -466,20 +470,20 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
w_mth_inverse = (*env)->GetMethodID(env, wclass, "xInverse", "()V");
|
||||
w_mth_xvalue = (*env)->GetMethodID(env, wclass, "xValue", "()V");
|
||||
|
||||
pclass = (*env)->FindClass(env, "org/jetbrains/sqlite/core/DB$ProgressObserver");
|
||||
pclass = (*env)->FindClass(env, "org/jetbrains/sqlite/SqliteDb$ProgressObserver");
|
||||
if(!pclass) return JNI_ERR;
|
||||
pclass = (*env)->NewWeakGlobalRef(env, pclass);
|
||||
pmethod = (*env)->GetMethodID(env, pclass, "progress", "(II)V");
|
||||
|
||||
phandleclass = (*env)->FindClass(env, "org/jetbrains/sqlite/ProgressHandler");
|
||||
if(!phandleclass) return JNI_ERR;
|
||||
phandleclass = (*env)->NewWeakGlobalRef(env, phandleclass);
|
||||
// phandleclass = (*env)->FindClass(env, "org/jetbrains/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;
|
||||
return JNI_VERSION_10;
|
||||
}
|
||||
|
||||
// FINALIZATION
|
||||
@@ -502,20 +506,20 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
|
||||
|
||||
if (pclass) (*env)->DeleteWeakGlobalRef(env, pclass);
|
||||
|
||||
if (phandleclass) (*env)->DeleteWeakGlobalRef(env, phandleclass);
|
||||
// if (phandleclass) (*env)->DeleteWeakGlobalRef(env, phandleclass);
|
||||
}
|
||||
|
||||
|
||||
// WRAPPERS for sqlite_* functions //////////////////////////////////
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_shared_1cache(
|
||||
JNIEnv *env, jobject this, jboolean enable)
|
||||
{
|
||||
return sqlite3_enable_shared_cache(enable ? 1 : 0);
|
||||
}
|
||||
//JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_shared_1cache(
|
||||
// JNIEnv *env, jobject this, jboolean enable)
|
||||
//{
|
||||
// return sqlite3_enable_shared_cache(enable ? 1 : 0);
|
||||
//}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_enable_1load_1extension(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_enable_1load_1extension(
|
||||
JNIEnv *env, jobject this, jboolean enable)
|
||||
{
|
||||
sqlite3 *db = gethandle(env, this);
|
||||
@@ -529,40 +533,39 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_enable_1load_1ext
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB__1open_1utf8(
|
||||
JNIEnv *env, jobject this, jbyteArray file, jint flags)
|
||||
{
|
||||
sqlite3 *db;
|
||||
int ret;
|
||||
char *file_bytes;
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_open(JNIEnv *env, jobject this, jbyteArray file, jint flags) {
|
||||
int ret;
|
||||
sqlite3 *db;
|
||||
char *file_bytes;
|
||||
|
||||
db = gethandle(env, this);
|
||||
if (db) {
|
||||
throwex_msg(env, "DB already open");
|
||||
sqlite3_close(db);
|
||||
return;
|
||||
}
|
||||
// compiled with SQLITE_OMIT_AUTOINIT
|
||||
ret = sqlite3_initialize();
|
||||
if (ret != SQLITE_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
utf8JavaByteArrayToUtf8Bytes(env, file, &file_bytes, NULL);
|
||||
if (!file_bytes) return;
|
||||
utf8JavaByteArrayToUtf8Bytes(env, file, &file_bytes, NULL);
|
||||
if (!file_bytes) {
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (ret != SQLITE_OK) {
|
||||
ret = sqlite3_extended_errcode(db);
|
||||
sqlite3_close(db);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Ignore failures, as we can tolerate regular result codes.
|
||||
(void) sqlite3_extended_result_codes(db, 1);
|
||||
sethandle(env, this, db);
|
||||
|
||||
// ignore failures, as we can tolerate regular result codes
|
||||
(void) sqlite3_extended_result_codes(db, 1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_interrupt(JNIEnv *env, jobject this)
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_interrupt(JNIEnv *env, jobject this)
|
||||
{
|
||||
sqlite3 *db = gethandle(env, this);
|
||||
if (!db)
|
||||
@@ -574,7 +577,7 @@ JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_interrupt(JNIEnv
|
||||
sqlite3_interrupt(db);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_busy_1timeout(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_busy_1timeout(
|
||||
JNIEnv *env, jobject this, jint ms)
|
||||
{
|
||||
sqlite3 *db = gethandle(env, this);
|
||||
@@ -593,7 +596,7 @@ int busyHandlerCallBack(void* callback, int nbPrevInvok) {
|
||||
struct BusyHandlerContext *busyHandlerContext = (struct BusyHandlerContext*) callback;
|
||||
(*(busyHandlerContext->vm))->AttachCurrentThread(busyHandlerContext->vm, (void **)&env, 0);
|
||||
|
||||
return (*env)->CallIntMethod( env,
|
||||
return (*env)->CallIntMethod( env,
|
||||
busyHandlerContext->obj,
|
||||
busyHandlerContext->methodId,
|
||||
nbPrevInvok);
|
||||
@@ -631,12 +634,12 @@ void change_busy_handler(JNIEnv *env, jobject nativeDB, jobject busyHandler)
|
||||
set_new_handler(env, nativeDB, "busyHandler", busyHandlerContext, &free_busy_handler);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_busy_1handler(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_busy_1handler(
|
||||
JNIEnv *env, jobject nativeDB, jobject busyHandler) {
|
||||
change_busy_handler(env, nativeDB, busyHandler);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_prepare_1utf8(
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_prepare_1utf8(
|
||||
JNIEnv *env, jobject this, jbyteArray sql)
|
||||
{
|
||||
sqlite3* db;
|
||||
@@ -666,7 +669,7 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_prepare_1utf8(
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB__1exec_1utf8(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB__1exec_1utf8(
|
||||
JNIEnv *env, jobject this, jbyteArray sql)
|
||||
{
|
||||
sqlite3* db;
|
||||
@@ -697,7 +700,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB__1exec_1utf8(
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_errmsg_1utf8(JNIEnv *env, jobject this)
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_errmsg_1utf8(JNIEnv *env, jobject this)
|
||||
{
|
||||
sqlite3 *db;
|
||||
const char *str;
|
||||
@@ -708,20 +711,20 @@ JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_errmsg_1utf8(J
|
||||
throwex_db_closed(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
str = (const char*) sqlite3_errmsg(db);
|
||||
if (!str) return NULL;
|
||||
return utf8BytesToDirectByteBuffer(env, str, strlen(str));
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_libversion_1utf8(
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_libversion_1utf8(
|
||||
JNIEnv *env, jobject this)
|
||||
{
|
||||
const char* version = sqlite3_libversion();
|
||||
return utf8BytesToDirectByteBuffer(env, version, strlen(version));
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_changes(
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_changes(
|
||||
JNIEnv *env, jobject this)
|
||||
{
|
||||
sqlite3 *db = gethandle(env, this);
|
||||
@@ -734,7 +737,7 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_changes(
|
||||
return sqlite3_changes64(db);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_total_1changes(
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_total_1changes(
|
||||
JNIEnv *env, jobject this)
|
||||
{
|
||||
sqlite3 *db = gethandle(env, this);
|
||||
@@ -747,7 +750,7 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_total_1changes(
|
||||
return sqlite3_total_changes64(db);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_finalize(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_finalize(
|
||||
JNIEnv *env, jobject this, jlong stmt)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -759,7 +762,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_finalize(
|
||||
return sqlite3_finalize(toref(stmt));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_step(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_step(
|
||||
JNIEnv *env, jobject this, jlong stmt)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -771,7 +774,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_step(
|
||||
return sqlite3_step(toref(stmt));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_reset(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_reset(
|
||||
JNIEnv *env, jobject this, jlong stmt)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -783,7 +786,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_reset(
|
||||
return sqlite3_reset(toref(stmt));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_clear_1bindings(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_clear_1bindings(
|
||||
JNIEnv *env, jobject this, jlong stmt)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -795,7 +798,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_clear_1bindings(
|
||||
return sqlite3_clear_bindings(toref(stmt));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1parameter_1count(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1parameter_1count(
|
||||
JNIEnv *env, jobject this, jlong stmt)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -807,7 +810,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1parameter_1
|
||||
return sqlite3_bind_parameter_count(toref(stmt));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1count(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1count(
|
||||
JNIEnv *env, jobject this, jlong stmt)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -819,7 +822,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1count(
|
||||
return sqlite3_column_count(toref(stmt));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1type(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1type(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -831,56 +834,40 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1type(
|
||||
return sqlite3_column_type(toref(stmt), col);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1decltype_1utf8(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
const char *str;
|
||||
//JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1table_1name_1utf8(
|
||||
// JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
//{
|
||||
// const char *str;
|
||||
//
|
||||
// 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));
|
||||
//}
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
throwex_stmt_finalized(env);
|
||||
return NULL;
|
||||
}
|
||||
//JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1name_1utf8(
|
||||
// JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
//{
|
||||
// const char *str;
|
||||
//
|
||||
// if (!stmt)
|
||||
// {
|
||||
// throwex_stmt_finalized(env);
|
||||
// return NULL;
|
||||
// }
|
||||
//
|
||||
// str = sqlite3_column_name(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_jetbrains_sqlite_core_NativeDB_column_1table_1name_1utf8(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1name_1utf8(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
throwex_stmt_finalized(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = sqlite3_column_name(toref(stmt), col);
|
||||
if (!str) return NULL;
|
||||
|
||||
return utf8BytesToDirectByteBuffer(env, str, strlen(str));
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1text_1utf8(
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1text_1utf8(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
sqlite3 *db;
|
||||
@@ -912,7 +899,7 @@ JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1text_1
|
||||
return utf8BytesToDirectByteBuffer(env, bytes, nbytes);
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1blob(
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1blob(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
sqlite3 *db;
|
||||
@@ -963,7 +950,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1blo
|
||||
return jBlob;
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1double(
|
||||
JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1double(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -975,7 +962,7 @@ JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1double
|
||||
return sqlite3_column_double(toref(stmt), col);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1long(
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1long(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -987,7 +974,7 @@ JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1long(
|
||||
return sqlite3_column_int64(toref(stmt), col);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1int(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1int(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint col)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -999,7 +986,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1int(
|
||||
return sqlite3_column_int(toref(stmt), col);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1null(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1null(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint pos)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -1011,7 +998,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1null(
|
||||
return sqlite3_bind_null(toref(stmt), pos);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1int(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1int(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint pos, jint v)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -1023,7 +1010,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1int(
|
||||
return sqlite3_bind_int(toref(stmt), pos, v);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1long(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1long(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint pos, jlong v)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -1035,7 +1022,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1long(
|
||||
return sqlite3_bind_int64(toref(stmt), pos, v);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1double(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1double(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint pos, jdouble v)
|
||||
{
|
||||
if (!stmt)
|
||||
@@ -1047,7 +1034,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1double(
|
||||
return sqlite3_bind_double(toref(stmt), pos, v);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1text_1utf8(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1text_1utf8(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint pos, jbyteArray v)
|
||||
{
|
||||
int rc;
|
||||
@@ -1069,7 +1056,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1text_1utf8(
|
||||
return rc;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1blob(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1blob(
|
||||
JNIEnv *env, jobject this, jlong stmt, jint pos, jbyteArray v)
|
||||
{
|
||||
jint rc;
|
||||
@@ -1090,14 +1077,14 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_bind_1blob(
|
||||
return rc;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1null(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1null(
|
||||
JNIEnv *env, jobject this, jlong context)
|
||||
{
|
||||
if (!context) return;
|
||||
sqlite3_result_null(toref(context));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1text_1utf8(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1text_1utf8(
|
||||
JNIEnv *env, jobject this, jlong context, jbyteArray value)
|
||||
{
|
||||
char* value_bytes;
|
||||
@@ -1117,7 +1104,7 @@ JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1text_1utf
|
||||
freeUtf8Bytes(value_bytes);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1blob(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1blob(
|
||||
JNIEnv *env, jobject this, jlong context, jobject value)
|
||||
{
|
||||
jbyte *bytes;
|
||||
@@ -1133,28 +1120,28 @@ JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1blob(
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, value, bytes, JNI_ABORT);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1double(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1double(
|
||||
JNIEnv *env, jobject this, jlong context, jdouble value)
|
||||
{
|
||||
if (!context) return;
|
||||
sqlite3_result_double(toref(context), value);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1long(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1long(
|
||||
JNIEnv *env, jobject this, jlong context, jlong value)
|
||||
{
|
||||
if (!context) return;
|
||||
sqlite3_result_int64(toref(context), value);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1int(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1int(
|
||||
JNIEnv *env, jobject this, jlong context, jint value)
|
||||
{
|
||||
if (!context) return;
|
||||
sqlite3_result_int(toref(context), value);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1error_1utf8(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1error_1utf8(
|
||||
JNIEnv *env, jobject this, jlong context, jbyteArray err)
|
||||
{
|
||||
char* err_bytes;
|
||||
@@ -1173,7 +1160,7 @@ JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_result_1error_1ut
|
||||
freeUtf8Bytes(err_bytes);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1text_1utf8(
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1text_1utf8(
|
||||
JNIEnv *env, jobject this, jobject f, jint arg)
|
||||
{
|
||||
const char* bytes;
|
||||
@@ -1188,7 +1175,7 @@ JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1text_1u
|
||||
return utf8BytesToDirectByteBuffer(env, bytes, nbytes);
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1blob(
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1blob(
|
||||
JNIEnv *env, jobject this, jobject f, jint arg)
|
||||
{
|
||||
int length;
|
||||
@@ -1209,28 +1196,28 @@ JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1blob
|
||||
return jBlob;
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1double(
|
||||
JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1double(
|
||||
JNIEnv *env, jobject this, jobject f, jint arg)
|
||||
{
|
||||
sqlite3_value *value = tovalue(env, f, arg);
|
||||
return value ? sqlite3_value_double(value) : 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1long(
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1long(
|
||||
JNIEnv *env, jobject this, jobject f, jint arg)
|
||||
{
|
||||
sqlite3_value *value = tovalue(env, f, arg);
|
||||
return value ? sqlite3_value_int64(value) : 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1int(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1int(
|
||||
JNIEnv *env, jobject this, jobject f, jint arg)
|
||||
{
|
||||
sqlite3_value *value = tovalue(env, f, arg);
|
||||
return value ? sqlite3_value_int(value) : 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_value_1type(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1type(
|
||||
JNIEnv *env, jobject this, jobject func, jint arg)
|
||||
{
|
||||
return sqlite3_value_type(tovalue(env, func, arg));
|
||||
@@ -1254,7 +1241,7 @@ void free_udf_func(void *udfToFree) {
|
||||
free(udf);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_create_1function_1utf8(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_create_1function_1utf8(
|
||||
JNIEnv *env, jobject nativeDB, jbyteArray name, jobject func, jint nArgs, jint flags)
|
||||
{
|
||||
jint ret = 0;
|
||||
@@ -1305,7 +1292,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_create_1function_
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_destroy_1function_1utf8(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_destroy_1function_1utf8(
|
||||
JNIEnv *env, jobject nativeDB, jbyteArray name)
|
||||
{
|
||||
jint ret = 0;
|
||||
@@ -1313,7 +1300,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_destroy_1function
|
||||
|
||||
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
|
||||
);
|
||||
@@ -1322,7 +1309,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_destroy_1function
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_create_1collation_1utf8(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_create_1collation_1utf8(
|
||||
JNIEnv *env, jobject this, jbyteArray name, jobject func)
|
||||
{
|
||||
jint ret = 0;
|
||||
@@ -1352,7 +1339,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_create_1collation
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_destroy_1collation_1utf8(
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_destroy_1collation_1utf8(
|
||||
JNIEnv *env, jobject this, jbyteArray name)
|
||||
{
|
||||
jint ret = 0;
|
||||
@@ -1369,7 +1356,7 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_destroy_1collatio
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_limit(JNIEnv *env, jobject this, jint id, jint value)
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_limit(JNIEnv *env, jobject this, jint id, jint value)
|
||||
{
|
||||
sqlite3* db;
|
||||
|
||||
@@ -1386,73 +1373,73 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_limit(JNIEnv *env
|
||||
|
||||
// COMPOUND FUNCTIONS ///////////////////////////////////////////////
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_sqlite_core_NativeDB_column_1metadata(
|
||||
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;
|
||||
|
||||
db = gethandle(env, this);
|
||||
if (!db)
|
||||
{
|
||||
throwex_db_closed(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
throwex_stmt_finalized(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
// 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; }
|
||||
|
||||
(*env)->SetBooleanArrayRegion(env, colData, 0, 3, colDataRaw);
|
||||
(*env)->SetObjectArrayElement(env, array, i, colData);
|
||||
}
|
||||
|
||||
free(colDataRaw);
|
||||
|
||||
return array;
|
||||
}
|
||||
//JNIEXPORT jobjectArray JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1metadata(
|
||||
// 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;
|
||||
//
|
||||
// db = gethandle(env, this);
|
||||
// if (!db)
|
||||
// {
|
||||
// throwex_db_closed(env);
|
||||
// return NULL;
|
||||
// }
|
||||
//
|
||||
// if (!stmt)
|
||||
// {
|
||||
// throwex_stmt_finalized(env);
|
||||
// return NULL;
|
||||
// }
|
||||
//
|
||||
// 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; }
|
||||
//
|
||||
// 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);
|
||||
//
|
||||
// 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
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// // 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; }
|
||||
//
|
||||
// (*env)->SetBooleanArrayRegion(env, colData, 0, 3, colDataRaw);
|
||||
// (*env)->SetObjectArrayElement(env, array, i, colData);
|
||||
// }
|
||||
//
|
||||
// free(colDataRaw);
|
||||
//
|
||||
// return array;
|
||||
//}
|
||||
|
||||
// backup function
|
||||
|
||||
@@ -1529,8 +1516,8 @@ void copyLoop(JNIEnv *env, sqlite3_backup *pBackup, jobject progress,
|
||||
** 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_jetbrains_sqlite_core_NativeDB_backup(
|
||||
JNIEnv *env, jobject this,
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_backup(
|
||||
JNIEnv *env, jobject this,
|
||||
jbyteArray zDBName,
|
||||
jbyteArray zFilename, /* Name of file to back up to */
|
||||
jobject observer, /* Progress function to invoke */
|
||||
@@ -1598,10 +1585,10 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_backup(
|
||||
#else
|
||||
return SQLITE_INTERNAL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_restore(
|
||||
JNIEnv *env, jobject this,
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_restore(
|
||||
JNIEnv *env, jobject this,
|
||||
jbyteArray zDBName,
|
||||
jbyteArray zFilename, /* Name of file to restore from */
|
||||
jobject observer, /* Progress function to invoke */
|
||||
@@ -1674,75 +1661,75 @@ JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_core_NativeDB_restore(
|
||||
|
||||
// Progress handler
|
||||
|
||||
struct ProgressHandlerContext {
|
||||
JavaVM *vm;
|
||||
jmethodID mth;
|
||||
jobject phandler;
|
||||
};
|
||||
//struct ProgressHandlerContext {
|
||||
// JavaVM *vm;
|
||||
// jmethodID mth;
|
||||
// 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, progressHandlerContext->mth);
|
||||
return rv;
|
||||
}
|
||||
//static void change_progress_handler(JNIEnv *env, jobject nativeDB, jobject progressHandler, jint vmCalls)
|
||||
//{
|
||||
// sqlite3 *db;
|
||||
//
|
||||
// db = gethandle(env, nativeDB);
|
||||
// if (!db){
|
||||
// throwex_db_closed(env);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// struct ProgressHandlerContext* progressHandlerContext = NULL;
|
||||
//
|
||||
// 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");
|
||||
// }
|
||||
//
|
||||
// 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);
|
||||
//}
|
||||
|
||||
static void change_progress_handler(JNIEnv *env, jobject nativeDB, jobject progressHandler, jint vmCalls)
|
||||
{
|
||||
sqlite3 *db;
|
||||
|
||||
db = gethandle(env, nativeDB);
|
||||
if (!db){
|
||||
throwex_db_closed(env);
|
||||
return;
|
||||
}
|
||||
|
||||
struct ProgressHandlerContext* progressHandlerContext = NULL;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_register_1progress_1handler(
|
||||
JNIEnv *env,
|
||||
jobject nativeDB,
|
||||
jint vmCalls,
|
||||
jobject progressHandler
|
||||
)
|
||||
{
|
||||
change_progress_handler(env, nativeDB, progressHandler, vmCalls);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_clear_1progress_1handler(
|
||||
JNIEnv *env,
|
||||
jobject nativeDB
|
||||
)
|
||||
{
|
||||
change_progress_handler(env, nativeDB, NULL, 0);
|
||||
}
|
||||
//JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_register_1progress_1handler(
|
||||
// JNIEnv *env,
|
||||
// jobject nativeDB,
|
||||
// jint vmCalls,
|
||||
// jobject progressHandler
|
||||
//)
|
||||
//{
|
||||
// change_progress_handler(env, nativeDB, progressHandler, vmCalls);
|
||||
//}
|
||||
//
|
||||
//JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_clear_1progress_1handler(
|
||||
// JNIEnv *env,
|
||||
// jobject nativeDB
|
||||
//)
|
||||
//{
|
||||
// change_progress_handler(env, nativeDB, NULL, 0);
|
||||
//}
|
||||
|
||||
// Update hook
|
||||
|
||||
@@ -1778,7 +1765,7 @@ static void clear_update_listener(JNIEnv *env, jobject nativeDB){
|
||||
set_new_handler(env, nativeDB, "updateListener", NULL, &free_update_handler);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_set_1update_1listener(JNIEnv *env, jobject nativeDB, jboolean enabled) {
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_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");
|
||||
@@ -1826,7 +1813,7 @@ void clear_commit_listener(JNIEnv *env, jobject nativeDB, sqlite3 *db) {
|
||||
set_new_handler(env, nativeDB, "commitListener", NULL, freeCommitHandlerCtx);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_set_1commit_1listener(JNIEnv *env, jobject nativeDB, jboolean enabled) {
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_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));
|
||||
@@ -1841,13 +1828,13 @@ JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB_set_1commit_1list
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_core_NativeDB__1close(
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB__1close(
|
||||
JNIEnv *env, jobject nativeDB)
|
||||
{
|
||||
sqlite3 *db = gethandle(env, nativeDB);
|
||||
if (db)
|
||||
{
|
||||
change_progress_handler(env, nativeDB, NULL, 0);
|
||||
// change_progress_handler(env, nativeDB, NULL, 0);
|
||||
change_busy_handler(env, nativeDB, NULL);
|
||||
clear_commit_listener(env, nativeDB, db);
|
||||
clear_update_listener(env, nativeDB);
|
||||
442
platform/sqlite/sqlite/NativeDB.h
Normal file
442
platform/sqlite/sqlite/NativeDB.h
Normal file
@@ -0,0 +1,442 @@
|
||||
#include <jni.h>
|
||||
/* Header for class org_sqlite__NativeDB */
|
||||
|
||||
#ifndef _Included_org_jetbrains_sqlite_NativeDB
|
||||
#define _Included_org_jetbrains_sqlite_NativeDB
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef org_jetbrains_sqlite_NativeDB_DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS
|
||||
#define org_jetbrains_sqlite_NativeDB_DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS 100L
|
||||
#undef org_jetbrains_sqlite_NativeDB_DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL
|
||||
#define org_jetbrains_sqlite_NativeDB_DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL 3L
|
||||
#undef org_jetbrains_sqlite_NativeDB_DEFAULT_PAGES_PER_BACKUP_STEP
|
||||
#define org_jetbrains_sqlite_NativeDB_DEFAULT_PAGES_PER_BACKUP_STEP 100L
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: open
|
||||
* Signature: ([BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_open
|
||||
(JNIEnv *, jobject, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: _close
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB__1close
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: _exec_utf8
|
||||
* Signature: ([B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB__1exec_1utf8
|
||||
(JNIEnv *, jobject, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: shared_cache
|
||||
* Signature: (Z)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_shared_1cache
|
||||
(JNIEnv *, jobject, jboolean);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: enable_load_extension
|
||||
* Signature: (Z)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_enable_1load_1extension
|
||||
(JNIEnv *, jobject, jboolean);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: interrupt
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_interrupt
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: busy_timeout
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_busy_1timeout
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: busy_handler
|
||||
* Signature: (Lorg/sqlite/BusyHandler;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_busy_1handler
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: prepare_utf8
|
||||
* Signature: ([B)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_prepare_1utf8
|
||||
(JNIEnv *, jobject, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: errmsg_utf8
|
||||
* Signature: ()Ljava/nio/ByteBuffer;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_errmsg_1utf8
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: libversion_utf8
|
||||
* Signature: ()Ljava/nio/ByteBuffer;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_libversion_1utf8
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: changes
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_changes
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: total_changes
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_total_1changes
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: finalize
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_finalize
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: step
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_step
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: reset
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_reset
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: clear_bindings
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_clear_1bindings
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_parameter_count
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1parameter_1count
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_count
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1count
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_type
|
||||
* Signature: (JI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1type
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_text_utf8
|
||||
* Signature: (JI)Ljava/nio/ByteBuffer;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1text_1utf8
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_blob
|
||||
* Signature: (JI)Ljava/nio/ByteBuffer;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1blob
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_double
|
||||
* Signature: (JI)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1double
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_long
|
||||
* Signature: (JI)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1long
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: column_int
|
||||
* Signature: (JI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_column_1int
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_null
|
||||
* Signature: (JI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1null
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_int
|
||||
* Signature: (JII)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1int
|
||||
(JNIEnv *, jobject, jlong, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_long
|
||||
* Signature: (JIJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1long
|
||||
(JNIEnv *, jobject, jlong, jint, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_double
|
||||
* Signature: (JID)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1double
|
||||
(JNIEnv *, jobject, jlong, jint, jdouble);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_text_utf8
|
||||
* Signature: (JI[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1text_1utf8
|
||||
(JNIEnv *, jobject, jlong, jint, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: bind_blob
|
||||
* Signature: (JI[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_bind_1blob
|
||||
(JNIEnv *, jobject, jlong, jint, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_null
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1null
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_text_utf8
|
||||
* Signature: (J[B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1text_1utf8
|
||||
(JNIEnv *, jobject, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_blob
|
||||
* Signature: (J[B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1blob
|
||||
(JNIEnv *, jobject, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_double
|
||||
* Signature: (JD)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1double
|
||||
(JNIEnv *, jobject, jlong, jdouble);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_long
|
||||
* Signature: (JJ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1long
|
||||
(JNIEnv *, jobject, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_int
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1int
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: result_error_utf8
|
||||
* Signature: (J[B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_result_1error_1utf8
|
||||
(JNIEnv *, jobject, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: value_text_utf8
|
||||
* Signature: (Lorg/sqlite/Function;I)Ljava/nio/ByteBuffer;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1text_1utf8
|
||||
(JNIEnv *, jobject, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: value_blob
|
||||
* Signature: (Lorg/sqlite/Function;I)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1blob
|
||||
(JNIEnv *, jobject, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: value_double
|
||||
* Signature: (Lorg/sqlite/Function;I)D
|
||||
*/
|
||||
JNIEXPORT jdouble JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1double
|
||||
(JNIEnv *, jobject, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: value_long
|
||||
* Signature: (Lorg/sqlite/Function;I)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1long
|
||||
(JNIEnv *, jobject, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: value_int
|
||||
* Signature: (Lorg/sqlite/Function;I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1int
|
||||
(JNIEnv *, jobject, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: value_type
|
||||
* Signature: (Lorg/sqlite/Function;I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_value_1type
|
||||
(JNIEnv *, jobject, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: create_function_utf8
|
||||
* Signature: ([BLorg/sqlite/Function;II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_create_1function_1utf8
|
||||
(JNIEnv *, jobject, jbyteArray, jobject, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: destroy_function_utf8
|
||||
* Signature: ([B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_destroy_1function_1utf8
|
||||
(JNIEnv *, jobject, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: create_collation_utf8
|
||||
* Signature: ([BLorg/sqlite/Collation;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_create_1collation_1utf8
|
||||
(JNIEnv *, jobject, jbyteArray, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: destroy_collation_utf8
|
||||
* Signature: ([B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_destroy_1collation_1utf8
|
||||
(JNIEnv *, jobject, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: limit
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_limit
|
||||
(JNIEnv *, jobject, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: backup
|
||||
* Signature: ([B[BLorg/sqlite/core/DB/ProgressObserver;III)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_backup
|
||||
(JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jint, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: restore
|
||||
* Signature: ([B[BLorg/sqlite/core/DB/ProgressObserver;III)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_jetbrains_sqlite_NativeDB_restore
|
||||
(JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jint, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: set_commit_listener
|
||||
* Signature: (Z)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_set_1commit_1listener
|
||||
(JNIEnv *, jobject, jboolean);
|
||||
|
||||
/*
|
||||
* Class: org_jetbrains_sqlite_NativeDB
|
||||
* Method: set_update_listener
|
||||
* Signature: (Z)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_jetbrains_sqlite_NativeDB_set_1update_1listener
|
||||
(JNIEnv *, jobject, jboolean);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
1987
platform/sqlite/sqlite/jni.h
Normal file
1987
platform/sqlite/sqlite/jni.h
Normal file
File diff suppressed because it is too large
Load Diff
66
platform/sqlite/sqlite/linux/jni_md.h
Normal file
66
platform/sqlite/sqlite/linux/jni_md.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef JNIEXPORT
|
||||
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
|
||||
#ifdef ARM
|
||||
#define JNIEXPORT __attribute__((externally_visible,visibility("default")))
|
||||
#else
|
||||
#define JNIEXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define JNIEXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
|
||||
#ifdef ARM
|
||||
#define JNIIMPORT __attribute__((externally_visible,visibility("default")))
|
||||
#else
|
||||
#define JNIIMPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define JNIIMPORT
|
||||
#endif
|
||||
|
||||
#define JNICALL
|
||||
|
||||
typedef int jint;
|
||||
#ifdef _LP64
|
||||
typedef long jlong;
|
||||
#else
|
||||
typedef long long jlong;
|
||||
#endif
|
||||
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
||||
66
platform/sqlite/sqlite/mac/jni_md.h
Normal file
66
platform/sqlite/sqlite/mac/jni_md.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef JNIEXPORT
|
||||
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
|
||||
#ifdef ARM
|
||||
#define JNIEXPORT __attribute__((externally_visible,visibility("default")))
|
||||
#else
|
||||
#define JNIEXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define JNIEXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
|
||||
#ifdef ARM
|
||||
#define JNIIMPORT __attribute__((externally_visible,visibility("default")))
|
||||
#else
|
||||
#define JNIIMPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define JNIIMPORT
|
||||
#endif
|
||||
|
||||
#define JNICALL
|
||||
|
||||
typedef int jint;
|
||||
#ifdef _LP64
|
||||
typedef long jlong;
|
||||
#else
|
||||
typedef long long jlong;
|
||||
#endif
|
||||
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
||||
243616
platform/sqlite/sqlite/sqlite3.c
Normal file
243616
platform/sqlite/sqlite/sqlite3.c
Normal file
File diff suppressed because it is too large
Load Diff
12894
platform/sqlite/sqlite/sqlite3.h
Normal file
12894
platform/sqlite/sqlite/sqlite3.h
Normal file
File diff suppressed because it is too large
Load Diff
40
platform/sqlite/sqlite/win/jni_md.h
Normal file
40
platform/sqlite/sqlite/win/jni_md.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#ifndef JNIEXPORT
|
||||
#define JNIEXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#define JNIIMPORT __declspec(dllimport)
|
||||
#define JNICALL __stdcall
|
||||
|
||||
// 'long' is always 32 bit on windows so this matches what jdk expects
|
||||
typedef long jint;
|
||||
typedef __int64 jlong;
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
||||
@@ -1,13 +1,10 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
import org.jetbrains.sqlite.core.SqliteConnection;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.io.IOException;
|
||||
|
||||
/** <a href="https://www.sqlite.org/c3ref/busy_handler.html">...</a> */
|
||||
public abstract class BusyHandler {
|
||||
|
||||
/**
|
||||
* <a href="https://www.sqlite.org/c3ref/busy_handler.html">...</a>
|
||||
*
|
||||
@@ -25,11 +22,9 @@ public abstract class BusyHandler {
|
||||
* @param conn the SQLite connection
|
||||
* @param busyHandler the busyHandler
|
||||
*/
|
||||
private static void commitHandler(SqliteConnection conn, BusyHandler busyHandler)
|
||||
throws SQLException {
|
||||
|
||||
private static void commitHandler(SqliteConnection conn, BusyHandler busyHandler) throws IOException {
|
||||
if (conn.isClosed()) {
|
||||
throw new SQLException("connection closed");
|
||||
throw new IOException("connection closed");
|
||||
}
|
||||
|
||||
conn.db.busy_handler(busyHandler);
|
||||
@@ -42,7 +37,7 @@ public abstract class BusyHandler {
|
||||
* @param busyHandler the busyHandler
|
||||
*/
|
||||
public static void setHandler(SqliteConnection conn, BusyHandler busyHandler)
|
||||
throws SQLException {
|
||||
throws IOException {
|
||||
commitHandler(conn, busyHandler);
|
||||
}
|
||||
|
||||
@@ -51,7 +46,7 @@ public abstract class BusyHandler {
|
||||
*
|
||||
* @param conn the SQLite connection
|
||||
*/
|
||||
public static void clearHandler(SqliteConnection conn) throws SQLException {
|
||||
public static void clearHandler(SqliteConnection conn) throws IOException {
|
||||
commitHandler(conn, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
import org.jetbrains.sqlite.core.Codes;
|
||||
import org.jetbrains.sqlite.core.DB;
|
||||
import org.jetbrains.sqlite.core.SqliteConnection;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Provides an interface for creating SQLite user-defined collations.
|
||||
@@ -43,7 +39,7 @@ import java.sql.SQLException;
|
||||
*/
|
||||
public abstract class Collation {
|
||||
private SqliteConnection conn;
|
||||
private DB db;
|
||||
private SqliteDb db;
|
||||
|
||||
/**
|
||||
* Called by SQLite as a custom collation to compare two strings.
|
||||
@@ -62,16 +58,16 @@ public abstract class Collation {
|
||||
* @param name The name of the collation.
|
||||
* @param f The collation to register.
|
||||
*/
|
||||
public static void create(SqliteConnection conn, String name, Collation f) throws SQLException {
|
||||
public static void create(SqliteConnection conn, String name, Collation f) throws IOException {
|
||||
if (conn.isClosed()) {
|
||||
throw new SQLException("connection closed");
|
||||
throw new IOException("connection closed");
|
||||
}
|
||||
|
||||
f.conn = conn;
|
||||
f.db = f.conn.db;
|
||||
|
||||
if (f.db.create_collation(name, f) != Codes.SQLITE_OK) {
|
||||
throw new SQLException("error creating collation");
|
||||
if (f.db.create_collation(name, f) != SqliteCodes.SQLITE_OK) {
|
||||
throw new IOException("error creating collation");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +77,7 @@ public abstract class Collation {
|
||||
* @param conn The connection to remove the collation from.
|
||||
* @param name The name of the collation.
|
||||
*/
|
||||
public static void destroy(SqliteConnection conn, String name) throws SQLException {
|
||||
public static void destroy(SqliteConnection conn, String name) {
|
||||
conn.db.destroy_collation(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
import org.jetbrains.sqlite.core.Codes;
|
||||
import org.jetbrains.sqlite.core.DB;
|
||||
import org.jetbrains.sqlite.core.SqliteConnection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Provides an interface for creating SQLite user-defined functions.
|
||||
@@ -57,7 +53,7 @@ public abstract class Function {
|
||||
long value = 0; // pointer sqlite3_value**
|
||||
int args = 0;
|
||||
private SqliteConnection conn;
|
||||
private DB db;
|
||||
private SqliteDb db;
|
||||
|
||||
/**
|
||||
* Called by SQLite as a custom function. Should access arguments through <tt>value_*(int)</tt>,
|
||||
@@ -69,7 +65,7 @@ public abstract class Function {
|
||||
* Returns the number of arguments passed to the function. Can only be called from
|
||||
* <tt>xFunc()</tt>.
|
||||
*/
|
||||
protected final synchronized int args() throws SQLException {
|
||||
protected final synchronized int args() throws IOException {
|
||||
checkContext();
|
||||
return args;
|
||||
}
|
||||
@@ -78,7 +74,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to return a value.
|
||||
*
|
||||
*/
|
||||
protected final synchronized void result(byte[] value) throws SQLException {
|
||||
protected final synchronized void result(byte[] value) throws IOException {
|
||||
checkContext();
|
||||
db.result_blob(context, value);
|
||||
}
|
||||
@@ -87,7 +83,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to return a value.
|
||||
*
|
||||
*/
|
||||
protected final synchronized void result(double value) throws SQLException {
|
||||
protected final synchronized void result(double value) throws IOException {
|
||||
checkContext();
|
||||
db.result_double(context, value);
|
||||
}
|
||||
@@ -96,7 +92,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to return a value.
|
||||
*
|
||||
*/
|
||||
protected final synchronized void result(int value) throws SQLException {
|
||||
protected final synchronized void result(int value) throws IOException {
|
||||
checkContext();
|
||||
db.result_int(context, value);
|
||||
}
|
||||
@@ -105,13 +101,13 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to return a value.
|
||||
*
|
||||
*/
|
||||
protected final synchronized void result(long value) throws SQLException {
|
||||
protected final synchronized void result(long value) throws IOException {
|
||||
checkContext();
|
||||
db.result_long(context, value);
|
||||
}
|
||||
|
||||
/** Called by <tt>xFunc</tt> to return a value. */
|
||||
protected final synchronized void result() throws SQLException {
|
||||
protected final synchronized void result() throws IOException {
|
||||
checkContext();
|
||||
db.result_null(context);
|
||||
}
|
||||
@@ -120,7 +116,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to return a value.
|
||||
*
|
||||
*/
|
||||
protected final synchronized void result(String value) throws SQLException {
|
||||
protected final synchronized void result(String value) throws IOException {
|
||||
checkContext();
|
||||
db.result_text(context, value);
|
||||
}
|
||||
@@ -129,7 +125,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to throw an error.
|
||||
*
|
||||
*/
|
||||
protected final synchronized void error(String err) throws SQLException {
|
||||
protected final synchronized void error(String err) throws IOException {
|
||||
checkContext();
|
||||
db.result_error(context, err);
|
||||
}
|
||||
@@ -138,7 +134,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to access the value of an argument.
|
||||
*
|
||||
*/
|
||||
protected final synchronized String value_text(int arg) throws SQLException {
|
||||
protected final synchronized String value_text(int arg) throws IOException {
|
||||
checkValue(arg);
|
||||
return db.value_text(this, arg);
|
||||
}
|
||||
@@ -147,7 +143,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to access the value of an argument.
|
||||
*
|
||||
*/
|
||||
protected final synchronized byte[] value_blob(int arg) throws SQLException {
|
||||
protected final synchronized byte[] value_blob(int arg) throws IOException {
|
||||
checkValue(arg);
|
||||
return db.value_blob(this, arg);
|
||||
}
|
||||
@@ -156,7 +152,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to access the value of an argument.
|
||||
*
|
||||
*/
|
||||
protected final synchronized double value_double(int arg) throws SQLException {
|
||||
protected final synchronized double value_double(int arg) throws IOException {
|
||||
checkValue(arg);
|
||||
return db.value_double(this, arg);
|
||||
}
|
||||
@@ -165,7 +161,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to access the value of an argument.
|
||||
*
|
||||
*/
|
||||
protected final synchronized int value_int(int arg) throws SQLException {
|
||||
protected final synchronized int value_int(int arg) throws IOException {
|
||||
checkValue(arg);
|
||||
return db.value_int(this, arg);
|
||||
}
|
||||
@@ -174,7 +170,7 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to access the value of an argument.
|
||||
*
|
||||
*/
|
||||
protected final synchronized long value_long(int arg) throws SQLException {
|
||||
protected final synchronized long value_long(int arg) throws IOException {
|
||||
checkValue(arg);
|
||||
return db.value_long(this, arg);
|
||||
}
|
||||
@@ -183,26 +179,26 @@ public abstract class Function {
|
||||
* Called by <tt>xFunc</tt> to access the value of an argument.
|
||||
*
|
||||
*/
|
||||
protected final synchronized int value_type(int arg) throws SQLException {
|
||||
protected final synchronized int value_type(int arg) throws IOException {
|
||||
checkValue(arg);
|
||||
return db.value_type(this, arg);
|
||||
}
|
||||
|
||||
/** */
|
||||
private void checkContext() throws SQLException {
|
||||
private void checkContext() throws IOException {
|
||||
if (conn == null || conn.db == null || context == 0) {
|
||||
throw new SQLException("no context, not allowed to read value");
|
||||
throw new IOException("no context, not allowed to read value");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private void checkValue(int arg) throws SQLException {
|
||||
private void checkValue(int arg) throws IOException {
|
||||
if (conn == null || conn.db == null || value == 0) {
|
||||
throw new SQLException("not in value access state");
|
||||
throw new IOException("not in value access state");
|
||||
}
|
||||
if (arg >= args) {
|
||||
throw new SQLException("arg " + arg + " out bounds [0," + args + ")");
|
||||
throw new IOException("arg " + arg + " out bounds [0," + args + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +209,7 @@ public abstract class Function {
|
||||
* @param name The name of the function.
|
||||
* @param f The function to register.
|
||||
*/
|
||||
public static void create(SqliteConnection conn, String name, Function f) throws SQLException {
|
||||
public static void create(SqliteConnection conn, String name, Function f) throws IOException {
|
||||
create(conn, name, f, 0);
|
||||
}
|
||||
|
||||
@@ -226,7 +222,7 @@ public abstract class Function {
|
||||
* @param flags Extra flags to pass, such as {@link #FLAG_DETERMINISTIC}
|
||||
*/
|
||||
public static void create(SqliteConnection conn, String name, Function f, int flags)
|
||||
throws SQLException {
|
||||
throws IOException {
|
||||
create(conn, name, f, -1, flags);
|
||||
}
|
||||
|
||||
@@ -240,20 +236,20 @@ public abstract class Function {
|
||||
* @param flags Extra flags to pass, such as {@link #FLAG_DETERMINISTIC}
|
||||
*/
|
||||
public static void create(SqliteConnection conn, String name, Function f, int nArgs, int flags)
|
||||
throws SQLException {
|
||||
throws IOException {
|
||||
if (conn.isClosed()) {
|
||||
throw new SQLException("connection closed");
|
||||
throw new IOException("connection closed");
|
||||
}
|
||||
|
||||
f.conn = conn;
|
||||
f.db = f.conn.db;
|
||||
|
||||
if (nArgs < -1 || nArgs > 127) {
|
||||
throw new SQLException("invalid args provided: " + nArgs);
|
||||
throw new IOException("invalid args provided: " + nArgs);
|
||||
}
|
||||
|
||||
if (f.db.create_function(name, f, nArgs, flags) != Codes.SQLITE_OK) {
|
||||
throw new SQLException("error creating function");
|
||||
if (f.db.create_function(name, f, nArgs, flags) != SqliteCodes.SQLITE_OK) {
|
||||
throw new IOException("error creating function");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +260,7 @@ public abstract class Function {
|
||||
* @param name The name of the function.
|
||||
* @param nArgs Ignored.
|
||||
*/
|
||||
public static void destroy(SqliteConnection conn, String name, int nArgs) throws SQLException {
|
||||
public static void destroy(SqliteConnection conn, String name, int nArgs) {
|
||||
conn.db.destroy_function(name);
|
||||
}
|
||||
|
||||
@@ -274,7 +270,7 @@ public abstract class Function {
|
||||
* @param conn The connection to remove the function from.
|
||||
* @param name The name of the function.
|
||||
*/
|
||||
public static void destroy(SqliteConnection conn, String name) throws SQLException {
|
||||
public static void destroy(SqliteConnection conn, String name) {
|
||||
destroy(conn, name, -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import org.jetbrains.sqlite.core.Codes
|
||||
import org.jetbrains.sqlite.core.DB
|
||||
import org.jetbrains.sqlite.core.stepInBatch
|
||||
|
||||
class IntBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramCount) {
|
||||
private var batch: IntArray = IntArray(paramCount * batchCountHint)
|
||||
|
||||
@@ -28,12 +24,12 @@ class IntBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramCoun
|
||||
batch[batchPosition + 2] = v3
|
||||
}
|
||||
|
||||
override fun bindParams(pointer: Long, db: DB) {
|
||||
override fun bindParams(pointer: Long, db: SqliteDb) {
|
||||
assert(batchQueryCount == 0)
|
||||
for ((index, value) in batch.withIndex()) {
|
||||
val status = db.bind_int(pointer, index + 1, value) and 0xFF
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,13 +46,13 @@ class IntBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramCoun
|
||||
}
|
||||
}
|
||||
|
||||
override fun executeBatch(pointer: Long, db: DB) {
|
||||
override fun executeBatch(pointer: Long, db: SqliteDb) {
|
||||
for (batchIndex in 0 until batchQueryCount) {
|
||||
db.reset(pointer)
|
||||
for (index in 0 until paramCount) {
|
||||
val status = db.bind_int(pointer, index + 1, batch[batchIndex * paramCount + index]) and 0xFF
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +82,12 @@ class LongBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramCou
|
||||
batch[batchPosition + 2] = v3
|
||||
}
|
||||
|
||||
override fun bindParams(pointer: Long, db: DB) {
|
||||
override fun bindParams(pointer: Long, db: SqliteDb) {
|
||||
assert(batchQueryCount == 0)
|
||||
for ((index, value) in batch.withIndex()) {
|
||||
val status = db.bind_long(pointer, index + 1, value) and 0xFF
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,13 +104,13 @@ class LongBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramCou
|
||||
}
|
||||
}
|
||||
|
||||
override fun executeBatch(pointer: Long, db: DB) {
|
||||
override fun executeBatch(pointer: Long, db: SqliteDb) {
|
||||
for (batchIndex in 0 until batchQueryCount) {
|
||||
db.reset(pointer)
|
||||
for (index in 0 until paramCount) {
|
||||
val status = db.bind_long(pointer, index + 1, batch[batchIndex * paramCount + index]) and 0xFF
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
362
platform/sqlite/src/org/jetbrains/sqlite/NativeDB.kt
Normal file
362
platform/sqlite/src/org/jetbrains/sqlite/NativeDB.kt
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com >
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
/** This class provides a thin JNI layer over the SQLite3 C API. */
|
||||
internal class NativeDB : SqliteDb() {
|
||||
// SQLite connection handle.
|
||||
private var pointer: Long = 0
|
||||
|
||||
@Suppress("unused")
|
||||
private val busyHandler: Long = 0
|
||||
@Suppress("unused")
|
||||
private val updateListener: Long = 0
|
||||
@Suppress("unused")
|
||||
private val commitListener: Long = 0
|
||||
|
||||
@Synchronized
|
||||
override fun open(file: String, openFlags: Int): Int {
|
||||
check(pointer == 0L) { "Database $file is already opened" }
|
||||
return open(stringToUtf8ByteArray(file), openFlags)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external override fun open(filename: ByteArray, openFlags: Int): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun _close()
|
||||
|
||||
@Synchronized
|
||||
override fun _exec(sql: String): Int {
|
||||
return _exec_utf8(stringToUtf8ByteArray(sql))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun _exec_utf8(sqlUtf8: ByteArray?): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun enable_load_extension(enable: Boolean): Int
|
||||
|
||||
external override fun interrupt()
|
||||
|
||||
@Synchronized
|
||||
external override fun busy_timeout(ms: Int)
|
||||
|
||||
@Synchronized
|
||||
external override fun busy_handler(busyHandler: BusyHandler?)
|
||||
|
||||
@Synchronized
|
||||
override fun prepare(sql: String): SafeStatementPointer {
|
||||
return SafeStatementPointer(db = this, pointer = prepare_utf8(stringToUtf8ByteArray(sql)))
|
||||
}
|
||||
|
||||
// byte[] instead of string is actually more performant
|
||||
@Synchronized
|
||||
external fun prepare_utf8(sqlUtf8: ByteArray?): Long
|
||||
|
||||
@Synchronized
|
||||
override fun errmsg(): String? {
|
||||
return utf8ByteBufferToString(errmsg_utf8() ?: return null)
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Synchronized
|
||||
external fun errmsg_utf8(): ByteBuffer?
|
||||
|
||||
@Synchronized
|
||||
override fun libversion(): String {
|
||||
return utf8ByteBufferToString(libversion_utf8())
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private external fun libversion_utf8(): ByteBuffer
|
||||
|
||||
@Synchronized
|
||||
external override fun changes(): Long
|
||||
|
||||
@Synchronized
|
||||
external override fun total_changes(): Long
|
||||
|
||||
@Synchronized
|
||||
external override fun finalize(stmt: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun step(stmt: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun reset(stmt: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun clear_bindings(stmt: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun bind_parameter_count(stmt: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun column_count(stmt: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun column_type(stmt: Long, col: Int): Int
|
||||
|
||||
@Synchronized
|
||||
override fun column_text(statementPointer: Long, zeroBasedColumnIndex: Int): String? {
|
||||
return utf8ByteBufferToString(column_text_utf8(statementPointer, zeroBasedColumnIndex) ?: return null)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun column_text_utf8(stmt: Long, col: Int): ByteBuffer?
|
||||
|
||||
@Synchronized
|
||||
external override fun column_blob(statementPointer: Long, zeroBasedColumnIndex: Int): ByteArray?
|
||||
|
||||
@Synchronized
|
||||
external override fun column_double(statementPointer: Long, zeroBasedColumnIndex: Int): Double
|
||||
|
||||
@Synchronized
|
||||
external override fun column_long(statementPointer: Long, zeroBasedColumnIndex: Int): Long
|
||||
|
||||
@Synchronized
|
||||
external override fun column_int(statementPointer: Long, zeroBasedColumnIndex: Int): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun bind_null(stmt: Long, oneBasedColumnIndex: Int): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun bind_int(stmt: Long, oneBasedColumnIndex: Int, v: Int): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun bind_long(stmt: Long, oneBasedColumnIndex: Int, v: Long): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun bind_double(stmt: Long, oneBasedColumnIndex: Int, v: Double): Int
|
||||
|
||||
@Synchronized
|
||||
override fun bind_text(stmt: Long, oneBasedColumnIndex: Int, v: String?): Int {
|
||||
return bind_text_utf8(stmt, oneBasedColumnIndex, stringToUtf8ByteArray(v))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun bind_text_utf8(stmt: Long, pos: Int, vUtf8: ByteArray?): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun bind_blob(stmt: Long, oneBasedColumnIndex: Int, v: ByteArray?): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun result_null(context: Long)
|
||||
|
||||
@Synchronized
|
||||
override fun result_text(context: Long, `val`: String?) {
|
||||
result_text_utf8(context, stringToUtf8ByteArray(`val`))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun result_text_utf8(context: Long, valUtf8: ByteArray?)
|
||||
|
||||
@Synchronized
|
||||
external override fun result_blob(context: Long, `val`: ByteArray?)
|
||||
|
||||
@Synchronized
|
||||
external override fun result_double(context: Long, `val`: Double)
|
||||
|
||||
@Synchronized
|
||||
external override fun result_long(context: Long, `val`: Long)
|
||||
|
||||
@Synchronized
|
||||
external override fun result_int(context: Long, `val`: Int)
|
||||
|
||||
@Synchronized
|
||||
override fun result_error(context: Long, err: String?) {
|
||||
result_error_utf8(context, stringToUtf8ByteArray(err))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun result_error_utf8(context: Long, errUtf8: ByteArray?)
|
||||
|
||||
@Synchronized
|
||||
override fun value_text(f: Function, arg: Int): String {
|
||||
return utf8ByteBufferToString(value_text_utf8(f, arg))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun value_text_utf8(f: Function?, argUtf8: Int): ByteBuffer
|
||||
|
||||
/** @see SqliteDb.value_blob
|
||||
*/
|
||||
@Synchronized
|
||||
external override fun value_blob(f: Function?, arg: Int): ByteArray?
|
||||
|
||||
@Synchronized
|
||||
external override fun value_double(f: Function?, arg: Int): Double
|
||||
|
||||
@Synchronized
|
||||
external override fun value_long(f: Function?, arg: Int): Long
|
||||
|
||||
@Synchronized
|
||||
external override fun value_int(f: Function?, arg: Int): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun value_type(f: Function, arg: Int): Int
|
||||
|
||||
/** @see SqliteDb.create_function
|
||||
*/
|
||||
@Synchronized
|
||||
override fun create_function(name: String, function: Function, nArgs: Int, flags: Int): Int {
|
||||
return create_function_utf8(nameUtf8 = nameToUtf8ByteArray(nameType = "function", name = name),
|
||||
func = function,
|
||||
nArgs = nArgs,
|
||||
flags = flags)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun create_function_utf8(nameUtf8: ByteArray, func: Function, nArgs: Int, flags: Int): Int
|
||||
|
||||
@Synchronized
|
||||
override fun destroy_function(name: String): Int {
|
||||
return destroy_function_utf8(nameToUtf8ByteArray("function", name))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun destroy_function_utf8(nameUtf8: ByteArray?): Int
|
||||
|
||||
@Synchronized
|
||||
override fun create_collation(name: String, collation: Collation): Int {
|
||||
return create_collation_utf8(nameToUtf8ByteArray("collation", name), collation)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun create_collation_utf8(nameUtf8: ByteArray, coll: Collation): Int
|
||||
|
||||
@Synchronized
|
||||
override fun destroy_collation(name: String): Int {
|
||||
return destroy_collation_utf8(nameToUtf8ByteArray(nameType = "collation", name = name))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun destroy_collation_utf8(nameUtf8: ByteArray?): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun limit(id: Int, value: Int): Int
|
||||
|
||||
override fun backup(dbName: String, destFileName: String, observer: ProgressObserver?): Int {
|
||||
return backup(dbNameUtf8 = stringToUtf8ByteArray(dbName),
|
||||
destFileNameUtf8 = stringToUtf8ByteArray(destFileName),
|
||||
observer = observer,
|
||||
sleepTimeMillis = DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS,
|
||||
nTimeouts = DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL,
|
||||
pagesPerStep = DEFAULT_PAGES_PER_BACKUP_STEP)
|
||||
}
|
||||
|
||||
override fun backup(dbName: String,
|
||||
destFileName: String,
|
||||
observer: ProgressObserver?,
|
||||
sleepTimeMillis: Int,
|
||||
nTimeouts: Int,
|
||||
pagesPerStep: Int): Int {
|
||||
return backup(dbNameUtf8 = stringToUtf8ByteArray(dbName),
|
||||
destFileNameUtf8 = stringToUtf8ByteArray(destFileName),
|
||||
observer = observer,
|
||||
sleepTimeMillis = sleepTimeMillis,
|
||||
nTimeouts = nTimeouts,
|
||||
pagesPerStep = pagesPerStep)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun backup(dbNameUtf8: ByteArray,
|
||||
destFileNameUtf8: ByteArray,
|
||||
observer: ProgressObserver?,
|
||||
sleepTimeMillis: Int,
|
||||
nTimeouts: Int,
|
||||
pagesPerStep: Int): Int
|
||||
|
||||
@Synchronized
|
||||
override fun restore(dbName: String, sourceFileName: String, observer: ProgressObserver?): Int {
|
||||
return restore(dbName = dbName,
|
||||
sourceFileName = sourceFileName,
|
||||
observer = observer,
|
||||
sleepTimeMillis = DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS,
|
||||
nTimeouts = DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL,
|
||||
pagesPerStep = DEFAULT_PAGES_PER_BACKUP_STEP)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun restore(dbName: String?,
|
||||
sourceFileName: String?,
|
||||
observer: ProgressObserver?,
|
||||
sleepTimeMillis: Int,
|
||||
nTimeouts: Int,
|
||||
pagesPerStep: Int): Int {
|
||||
return restore(
|
||||
dbNameUtf8 = stringToUtf8ByteArray(dbName),
|
||||
sourceFileName = stringToUtf8ByteArray(sourceFileName),
|
||||
observer = observer,
|
||||
sleepTimeMillis = sleepTimeMillis,
|
||||
nTimeouts = nTimeouts,
|
||||
pagesPerStep = pagesPerStep)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
external fun restore(dbNameUtf8: ByteArray?,
|
||||
sourceFileName: ByteArray?,
|
||||
observer: ProgressObserver?,
|
||||
sleepTimeMillis: Int,
|
||||
nTimeouts: Int,
|
||||
pagesPerStep: Int): Int
|
||||
|
||||
@Synchronized
|
||||
external override fun set_commit_listener(enabled: Boolean)
|
||||
|
||||
@Synchronized
|
||||
external override fun set_update_listener(enabled: Boolean)
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS = 100
|
||||
private const val DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL = 3
|
||||
private const val DEFAULT_PAGES_PER_BACKUP_STEP = 100
|
||||
|
||||
private fun nameToUtf8ByteArray(nameType: String, name: String): ByteArray {
|
||||
val nameUtf8 = stringToUtf8ByteArray(name)
|
||||
check(!(name.isEmpty() || nameUtf8.size > 255)) { "invalid $nameType name: '$name'" }
|
||||
return nameUtf8
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an IOException. Called from native code
|
||||
*/
|
||||
@Suppress("unused", "SpellCheckingInspection")
|
||||
@JvmStatic
|
||||
fun throwex(msg: String?) {
|
||||
throw IOException(msg)
|
||||
}
|
||||
|
||||
// called from native code (only to convert exception text on calling function)
|
||||
@JvmStatic
|
||||
fun stringToUtf8ByteArray(str: String?): ByteArray {
|
||||
return str!!.toByteArray(StandardCharsets.UTF_8)
|
||||
}
|
||||
|
||||
fun utf8ByteBufferToString(buffer: ByteBuffer): String {
|
||||
val bytes = ByteArray(buffer.remaining())
|
||||
buffer.get(bytes)
|
||||
return bytes.decodeToString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,16 @@
|
||||
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import org.jetbrains.sqlite.core.DB
|
||||
import org.jetbrains.sqlite.core.sqlBind
|
||||
import org.jetbrains.sqlite.core.stepInBatch
|
||||
|
||||
sealed class Binder {
|
||||
internal abstract val paramCount: Int
|
||||
|
||||
abstract val batchQueryCount: Int
|
||||
|
||||
internal abstract fun bindParams(pointer: Long, db: DB)
|
||||
|
||||
abstract fun addBatch()
|
||||
|
||||
abstract fun executeBatch(pointer: Long, db: DB)
|
||||
internal abstract fun bindParams(pointer: Long, db: SqliteDb)
|
||||
|
||||
internal abstract fun executeBatch(pointer: Long, db: SqliteDb)
|
||||
|
||||
internal abstract fun clearBatch()
|
||||
}
|
||||
@@ -28,12 +24,12 @@ object EmptyBinder : Binder() {
|
||||
override val batchQueryCount: Int
|
||||
get() = 0
|
||||
|
||||
override fun bindParams(pointer: Long, db: DB) {
|
||||
override fun bindParams(pointer: Long, db: SqliteDb) {
|
||||
}
|
||||
|
||||
override fun addBatch() = throw IllegalStateException()
|
||||
|
||||
override fun executeBatch(pointer: Long, db: DB) = throw IllegalStateException()
|
||||
override fun executeBatch(pointer: Long, db: SqliteDb) = throw IllegalStateException()
|
||||
|
||||
override fun clearBatch() {
|
||||
}
|
||||
@@ -55,7 +51,7 @@ sealed class BaseBinder(override val paramCount: Int) : Binder() {
|
||||
class ObjectBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramCount) {
|
||||
private var batch: Array<Any?> = arrayOfNulls(paramCount * batchCountHint)
|
||||
|
||||
override fun bindParams(pointer: Long, db: DB) {
|
||||
override fun bindParams(pointer: Long, db: SqliteDb) {
|
||||
assert(batchQueryCount == 0)
|
||||
for ((position, value) in batch.withIndex()) {
|
||||
sqlBind(pointer, position, value, db)
|
||||
@@ -74,7 +70,7 @@ class ObjectBinder(paramCount: Int, batchCountHint: Int = 1) : BaseBinder(paramC
|
||||
}
|
||||
}
|
||||
|
||||
override fun executeBatch(pointer: Long, db: DB) {
|
||||
override fun executeBatch(pointer: Long, db: SqliteDb) {
|
||||
for (batchIndex in 0 until batchQueryCount) {
|
||||
db.reset(pointer)
|
||||
for (position in 0 until paramCount) {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
import org.jetbrains.sqlite.core.SqliteConnection;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/** <a href="https://sqlite.org/c3ref/progress_handler.html">...</a> */
|
||||
public abstract class ProgressHandler {
|
||||
protected abstract int progress();
|
||||
|
||||
/**
|
||||
* Sets a progress handler for the connection.
|
||||
*
|
||||
* @param conn the SQLite connection
|
||||
* @param vmCalls the approximate number of virtual machine instructions that are evaluated
|
||||
* between successive invocations of the progressHandler
|
||||
* @param progressHandler the progressHandler
|
||||
*/
|
||||
public static void setHandler(
|
||||
SqliteConnection conn, int vmCalls, ProgressHandler progressHandler) throws SQLException {
|
||||
if (conn.isClosed()) {
|
||||
throw new SQLException("connection closed");
|
||||
}
|
||||
conn.db.register_progress_handler(vmCalls, progressHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any progress handler registered with the connection.
|
||||
*
|
||||
* @param conn the SQLite connection
|
||||
*/
|
||||
public static void clearHandler(SqliteConnection conn) throws SQLException {
|
||||
conn.db.clear_progress_handler();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
/** <a href="https://www.sqlite.org/c3ref/commit_hook.html">...</a> */
|
||||
public interface SQLiteCommitListener {
|
||||
|
||||
void onCommit();
|
||||
|
||||
void onRollback();
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import org.jetbrains.sqlite.core.SqliteConnection
|
||||
|
||||
class SQLiteConfig {
|
||||
// SQLite defaults to 0, but as https://github.com/xerial/sqlite-jdbc we use 3000
|
||||
var busyTimeout: Int = 3000
|
||||
@@ -16,7 +14,9 @@ class SQLiteConfig {
|
||||
// SQLite defaults to FULL (https://www.sqlite.org/pragma.html#pragma_synchronous),
|
||||
// but "FULL synchronous is very safe, but it is also slower", so
|
||||
// as we use WAL (see above) and WAL "is safe from corruption with synchronous=NORMAL", we use NORMAL as default.
|
||||
private var synchronous: SynchronousMode = SynchronousMode.NORMAL
|
||||
//private var synchronous: SynchronousMode = SynchronousMode.NORMAL
|
||||
|
||||
// SQLite is compiled with SQLITE_DEFAULT_WAL_SYNCHRONOUS=1
|
||||
|
||||
// set the default open mode of SQLite3
|
||||
var openModeFlag: Int = 0x00 or SQLiteOpenMode.READWRITE.flag or SQLiteOpenMode.CREATE.flag
|
||||
@@ -28,12 +28,13 @@ class SQLiteConfig {
|
||||
if (journalMode != JournalMode.DELETE) {
|
||||
yield("PRAGMA journal_mode = $journalMode")
|
||||
}
|
||||
if (synchronous != SynchronousMode.FULL) {
|
||||
yield("PRAGMA synchronous = $synchronous")
|
||||
}
|
||||
//if (synchronous != SynchronousMode.FULL && journalMode != synchronous) {
|
||||
// yield("PRAGMA synchronous = $synchronous")
|
||||
//}
|
||||
|
||||
// https://www.sqlite.org/pragma.html#pragma_temp_store
|
||||
yield("PRAGMA temp_store = MEMORY")
|
||||
yield("pragma cache_size = 2000")
|
||||
}.joinToString(";")
|
||||
connection.db.exec(sql)
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
* Copyright 2016 Magnus Reftel
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*--------------------------------------------------------------------------*/
|
||||
// --------------------------------------
|
||||
// sqlite-jdbc Project
|
||||
//
|
||||
// SQLiteException.java
|
||||
// Since: Jun 28, 2016
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
// --------------------------------------
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public final class SQLiteException extends SQLException {
|
||||
private final SQLiteErrorCode resultCode;
|
||||
|
||||
public SQLiteException(String message, SQLiteErrorCode resultCode) {
|
||||
super(message, null, resultCode.code & 0xff);
|
||||
this.resultCode = resultCode;
|
||||
}
|
||||
|
||||
public SQLiteErrorCode getResultCode() {
|
||||
return resultCode;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
public enum SQLiteLimits {
|
||||
SQLITE_LIMIT_LENGTH(0),
|
||||
SQLITE_LIMIT_SQL_LENGTH(1),
|
||||
SQLITE_LIMIT_COLUMN(2),
|
||||
SQLITE_LIMIT_EXPR_DEPTH(3),
|
||||
SQLITE_LIMIT_COMPOUND_SELECT(4),
|
||||
SQLITE_LIMIT_VDBE_OP(5),
|
||||
SQLITE_LIMIT_FUNCTION_ARG(6),
|
||||
SQLITE_LIMIT_ATTACHED(7),
|
||||
SQLITE_LIMIT_LIKE_PATTERN_LENGTH(8),
|
||||
SQLITE_LIMIT_VARIABLE_NUMBER(9),
|
||||
SQLITE_LIMIT_TRIGGER_DEPTH(10),
|
||||
SQLITE_LIMIT_WORKER_THREADS(11),
|
||||
SQLITE_LIMIT_PAGE_COUNT(12);
|
||||
|
||||
private final int id;
|
||||
|
||||
SQLiteLimits(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
/** <a href="https://www.sqlite.org/c3ref/update_hook.html">...</a> */
|
||||
public interface SQLiteUpdateListener {
|
||||
void onUpdate(Type type, String database, String table, long rowId);
|
||||
|
||||
enum Type {
|
||||
INSERT,
|
||||
DELETE,
|
||||
UPDATE
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite.core
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
/**
|
||||
* A class for safely wrapping calls to a native pointer to a statement, ensuring no other thread
|
||||
@@ -9,11 +9,8 @@ internal class SafeStatementPointer(
|
||||
// store a reference to the DB, to lock it before any safe function is called. This avoids
|
||||
// deadlocking by locking the DB. All calls with the raw pointer are synchronized with the DB
|
||||
// anyway, so making a separate lock would be pointless
|
||||
private val db: SqliteDb,
|
||||
@JvmField
|
||||
@PublishedApi
|
||||
internal val db: DB,
|
||||
@JvmField
|
||||
@PublishedApi
|
||||
internal val pointer: Long,
|
||||
) {
|
||||
/**
|
||||
@@ -64,7 +61,7 @@ internal class SafeStatementPointer(
|
||||
* @param task the function to run
|
||||
* @return the return of the passed in function
|
||||
*/
|
||||
inline fun safeRunInt(task: (db: DB, statementPointer: Long) -> Int): Int {
|
||||
inline fun safeRunInt(task: (db: SqliteDb, statementPointer: Long) -> Int): Int {
|
||||
synchronized(db) {
|
||||
ensureOpen()
|
||||
return task(db, pointer)
|
||||
@@ -77,7 +74,7 @@ internal class SafeStatementPointer(
|
||||
* @param task the function to run
|
||||
* @return the return code of the function
|
||||
*/
|
||||
inline fun <T> safeRun(task: (db: DB, statementPointer: Long) -> T): T {
|
||||
inline fun <T> safeRun(task: (db: SqliteDb, statementPointer: Long) -> T): T {
|
||||
synchronized(db) {
|
||||
ensureOpen()
|
||||
return task(db, pointer)
|
||||
@@ -1,18 +1,23 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:Suppress("RemoveExplicitTypeArguments")
|
||||
|
||||
package org.jetbrains.sqlite.core
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.sqlite.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : AutoCloseable {
|
||||
//private final AtomicInteger savePoint = new AtomicInteger(0);
|
||||
@JvmField
|
||||
internal val db: NativeDB
|
||||
|
||||
private val closed = AtomicBoolean(true)
|
||||
|
||||
val isClosed: Boolean
|
||||
get() = closed.get()
|
||||
|
||||
private var currentBusyTimeout: Int
|
||||
/**
|
||||
* @return The busy timeout value for the connection.
|
||||
@@ -25,45 +30,17 @@ class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : Aut
|
||||
db.busy_timeout(timeoutMillis)
|
||||
}
|
||||
|
||||
//
|
||||
///** @see Connection#setSavepoint() */
|
||||
//public SqliteSavepoint setSavepoint() throws SQLException {
|
||||
// checkOpen();
|
||||
// var sp = new SqliteSavepoint(savePoint.incrementAndGet());
|
||||
// getDatabase().exec(String.format("SAVEPOINT %s", sp.getSavepointName()));
|
||||
// return sp;
|
||||
//}
|
||||
//
|
||||
///** @see Connection#setSavepoint(String) */
|
||||
//public SqliteSavepoint setSavepoint(String name) throws SQLException {
|
||||
// checkOpen();
|
||||
// var sp = new SqliteSavepoint(savePoint.incrementAndGet(), name);
|
||||
// getDatabase().exec(String.format("SAVEPOINT %s", sp.getSavepointName()));
|
||||
// return sp;
|
||||
//}
|
||||
//
|
||||
///** @see Connection#releaseSavepoint(Savepoint) */
|
||||
//public void releaseSavepoint(Savepoint savepoint) throws SQLException {
|
||||
// checkOpen();
|
||||
// getDatabase()
|
||||
// .exec(String.format("RELEASE SAVEPOINT %s", savepoint.getSavepointName()));
|
||||
//}
|
||||
//
|
||||
///** @see Connection#rollback(Savepoint) */
|
||||
//public void rollback(Savepoint savepoint) throws SQLException {
|
||||
// checkOpen();
|
||||
// getDatabase()
|
||||
// .exec(
|
||||
// String.format("ROLLBACK TO SAVEPOINT %s", savepoint.getSavepointName())
|
||||
// );
|
||||
//}
|
||||
|
||||
init {
|
||||
file?.parent?.let { Files.createDirectories(it) }
|
||||
loadNativeDb()
|
||||
db = NativeDB()
|
||||
@Suppress("IfThenToElvis")
|
||||
db.open(if (file == null) ":memory:" else file.toAbsolutePath().normalize().toString(), config.openModeFlag)
|
||||
val status = db.open(if (file == null) ":memory:" else file.toAbsolutePath().normalize().toString(), config.openModeFlag) and 0xff
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw SqliteDb.newException(status, "", null)
|
||||
}
|
||||
closed.set(false)
|
||||
|
||||
try {
|
||||
config.apply(this)
|
||||
currentBusyTimeout = config.busyTimeout
|
||||
@@ -101,9 +78,6 @@ class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : Aut
|
||||
return SqlitePreparedStatement(connection = this, sql = sql, binder = binder)
|
||||
}
|
||||
|
||||
val isClosed: Boolean
|
||||
get() = db.isClosed
|
||||
|
||||
//
|
||||
///** @see Connection#setSavepoint() */
|
||||
//public SqliteSavepoint setSavepoint() throws SQLException {
|
||||
@@ -181,9 +155,9 @@ class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : Aut
|
||||
|
||||
internal fun step(statementPointer: Long, sql: String): Boolean {
|
||||
return when (val status = db.step(statementPointer) and 0xFF) {
|
||||
Codes.SQLITE_DONE -> true
|
||||
Codes.SQLITE_ROW -> false
|
||||
else -> throw DB.newSQLException(status, db.errmsg(), sql)
|
||||
SqliteCodes.SQLITE_DONE -> true
|
||||
SqliteCodes.SQLITE_ROW -> false
|
||||
else -> throw SqliteDb.newException(status, db.errmsg()!!, sql)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,8 +168,8 @@ class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : Aut
|
||||
|
||||
if (values is Int) {
|
||||
val status = db.bind_int(statementPointer, 1, values)
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -218,13 +192,13 @@ class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : Aut
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
if (!isClosed) {
|
||||
if (closed.compareAndSet(false, true)) {
|
||||
db.close()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkOpen() {
|
||||
check(!isClosed) { "database connection closed" }
|
||||
check(!closed.get()) { "database connection closed" }
|
||||
}
|
||||
|
||||
fun beginTransaction() {
|
||||
@@ -279,7 +253,7 @@ class SqliteConnection(file: Path?, config: SQLiteConfig = SQLiteConfig()) : Aut
|
||||
//}
|
||||
}
|
||||
|
||||
internal fun sqlBind(pointer: Long, index: Int, v: Any?, db: DB) {
|
||||
internal fun sqlBind(pointer: Long, index: Int, v: Any?, db: SqliteDb) {
|
||||
val position = index + 1
|
||||
val status = when (v) {
|
||||
null -> db.bind_null(pointer, position)
|
||||
@@ -293,20 +267,20 @@ internal fun sqlBind(pointer: Long, index: Int, v: Any?, db: DB) {
|
||||
else -> throw UnsupportedOperationException("Unexpected param type: ${v.javaClass}")
|
||||
} and 0xFF
|
||||
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun stepInBatch(statementPointer: Long, db: DB, batchIndex: Int) {
|
||||
internal fun stepInBatch(statementPointer: Long, db: SqliteDb, batchIndex: Int) {
|
||||
val status = db.step(statementPointer)
|
||||
if (status != DB.SQLITE_DONE) {
|
||||
if (status != SqliteCodes.SQLITE_DONE) {
|
||||
db.reset(statementPointer)
|
||||
if (status == DB.SQLITE_ROW) {
|
||||
if (status == SqliteCodes.SQLITE_ROW) {
|
||||
throw IllegalStateException("batch entry $batchIndex: query returns results")
|
||||
}
|
||||
else {
|
||||
throw db.newSQLException(status)
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
611
platform/sqlite/src/org/jetbrains/sqlite/SqliteDb.kt
Normal file
611
platform/sqlite/src/org/jetbrains/sqlite/SqliteDb.kt
Normal file
@@ -0,0 +1,611 @@
|
||||
/*
|
||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
internal abstract class SqliteDb {
|
||||
// tracer for statements to avoid unfinalized statements on db close
|
||||
private val statements = ConcurrentHashMap.newKeySet<SafeStatementPointer>()
|
||||
private val updateListeners = HashSet<SQLiteUpdateListener>()
|
||||
private val commitListeners = HashSet<SQLiteCommitListener>()
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Throws formatted SqliteException with error code and message.
|
||||
*/
|
||||
fun newException(errorCode: Int, errorMessage: String, sql: String? = null): SqliteException {
|
||||
val code = SqliteErrorCode.getErrorCode(errorCode)
|
||||
var text = if (code == SqliteErrorCode.UNKNOWN_ERROR) {
|
||||
"$code:$errorCode ($errorMessage)"
|
||||
}
|
||||
else {
|
||||
"$code ($errorMessage)"
|
||||
}
|
||||
if (sql != null) {
|
||||
text += " (sql=$sql)"
|
||||
}
|
||||
return SqliteException(message = text, resultCode = code)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aborts any pending operation and returns at its earliest opportunity.
|
||||
* See [http://www.sqlite.org/c3ref/interrupt.html](http://www.sqlite.org/c3ref/interrupt.html)
|
||||
*/
|
||||
abstract fun interrupt()
|
||||
|
||||
/**
|
||||
* Sets a [busy handler](http://www.sqlite.org/c3ref/busy_handler.html) that sleeps
|
||||
* for a specified amount of time when a table is locked.
|
||||
*
|
||||
* @param ms Time to sleep in milliseconds.
|
||||
* @see [http://www.sqlite.org/c3ref/busy_timeout.html](http://www.sqlite.org/c3ref/busy_timeout.html)
|
||||
*/
|
||||
abstract fun busy_timeout(ms: Int)
|
||||
|
||||
/**
|
||||
* Sets a [busy handler](http://www.sqlite.org/c3ref/busy_handler.html) that sleeps
|
||||
* for a specified amount of time when a table is locked.
|
||||
*
|
||||
* @see [http://www.sqlite.org/c3ref/busy_timeout.html](http://www.sqlite.org/c3ref/busy_handler.html)
|
||||
*/
|
||||
abstract fun busy_handler(busyHandler: BusyHandler?)
|
||||
|
||||
/**
|
||||
* Return English-language text that describes the error as either UTF-8 or UTF-16.
|
||||
*
|
||||
* @return Error description in English.
|
||||
* @see [http://www.sqlite.org/c3ref/errcode.html](http://www.sqlite.org/c3ref/errcode.html)
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
abstract fun errmsg(): String?
|
||||
|
||||
/**
|
||||
* Returns the value for SQLITE_VERSION, SQLITE_VERSION_NUMBER, and SQLITE_SOURCE_ID C
|
||||
* preprocessor macros that are associated with the library.
|
||||
*
|
||||
* @see [http://www.sqlite.org/c3ref/c_source_id.html](http://www.sqlite.org/c3ref/c_source_id.html)
|
||||
*/
|
||||
@Suppress("SpellCheckingInspection")
|
||||
abstract fun libversion(): String
|
||||
|
||||
/**
|
||||
* @return Number of rows that were changed, inserted or deleted by the last SQL statement
|
||||
* @see [http://www.sqlite.org/c3ref/changes.html](http://www.sqlite.org/c3ref/changes.html)
|
||||
*/
|
||||
abstract fun changes(): Long
|
||||
|
||||
/**
|
||||
* @return Number of row changes caused by INSERT, UPDATE or DELETE statements since the
|
||||
* database connection was opened.
|
||||
* @see [http://www.sqlite.org/c3ref/total_changes.html](http://www.sqlite.org/c3ref/total_changes.html)
|
||||
*/
|
||||
abstract fun total_changes(): Long
|
||||
|
||||
/**
|
||||
* Enables or disables loading of SQLite extensions.
|
||||
*
|
||||
* @param enable True to enable; false otherwise.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/load_extension.html](http://www.sqlite.org/c3ref/load_extension.html)
|
||||
*/
|
||||
abstract fun enable_load_extension(enable: Boolean): Int
|
||||
|
||||
/**
|
||||
* Execute an SQL statement using the process of compiling, evaluating, and destroying the prepared statement object.
|
||||
*
|
||||
* @param sql SQL statement to be executed.
|
||||
* @see [http://www.sqlite.org/c3ref/exec.html](http://www.sqlite.org/c3ref/exec.html)
|
||||
*/
|
||||
@Synchronized
|
||||
fun exec(sql: String) {
|
||||
val status = _exec(sql)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw newException(errorCode = status, errorMessage = errmsg()!!, sql = sql)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun open(file: String, openFlags: Int): Int
|
||||
|
||||
/**
|
||||
* Closes a database connection and finalizes any remaining statements before the closing
|
||||
* operation.
|
||||
*
|
||||
* @see [http://www.sqlite.org/c3ref/close.html](http://www.sqlite.org/c3ref/close.html)
|
||||
*/
|
||||
@Synchronized
|
||||
fun close() {
|
||||
// finalize any remaining statements before closing db
|
||||
for (element in statements) {
|
||||
try {
|
||||
element.internalClose()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
Logger.getInstance(SqliteDb::class.java).error(e)
|
||||
}
|
||||
}
|
||||
_close()
|
||||
}
|
||||
|
||||
/**
|
||||
* Complies an SQL statement.
|
||||
* @see [http://www.sqlite.org/c3ref/prepare.html](http://www.sqlite.org/c3ref/prepare.html)
|
||||
*/
|
||||
@Synchronized
|
||||
fun prepareForStatement(sql: String): SafeStatementPointer {
|
||||
val pointer = prepare(sql)
|
||||
check(statements.add(pointer)) { "Already added pointer to statements set" }
|
||||
return pointer
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a statement.
|
||||
*
|
||||
* @param safePtr the pointer wrapper to remove from internal structures
|
||||
* @param ptr the raw pointer to free
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/finalize.html](http://www.sqlite.org/c3ref/finalize.html)
|
||||
*/
|
||||
@Synchronized
|
||||
fun finalize(safePtr: SafeStatementPointer, ptr: Long): Int {
|
||||
try {
|
||||
return finalize(ptr)
|
||||
}
|
||||
finally {
|
||||
statements.remove(safePtr)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an SQLite interface to a database with the provided open flags.
|
||||
*
|
||||
* @param filename The database to open.
|
||||
* @param openFlags File opening configurations ([http://www.sqlite.org/c3ref/c_open_autoproxy.html](http://www.sqlite.org/c3ref/c_open_autoproxy.html))
|
||||
* @see [http://www.sqlite.org/c3ref/open.html](http://www.sqlite.org/c3ref/open.html)
|
||||
*/
|
||||
protected abstract fun open(filename: ByteArray, openFlags: Int): Int
|
||||
|
||||
/**
|
||||
* Closes the SQLite interface to a database.
|
||||
*
|
||||
* @see [http://www.sqlite.org/c3ref/close.html](http://www.sqlite.org/c3ref/close.html)
|
||||
*/
|
||||
protected abstract fun _close()
|
||||
|
||||
/**
|
||||
* Complies, evaluates, executes and commits an SQL statement.
|
||||
*
|
||||
* @param sql An SQL statement.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/exec.html](http://www.sqlite.org/c3ref/exec.html)
|
||||
*/
|
||||
abstract fun _exec(sql: String): Int
|
||||
|
||||
/**
|
||||
* Complies an SQL statement.
|
||||
*
|
||||
* @param sql An SQL statement.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/prepare.html](http://www.sqlite.org/c3ref/prepare.html)
|
||||
*/
|
||||
protected abstract fun prepare(sql: String): SafeStatementPointer
|
||||
|
||||
/**
|
||||
* Destroys a prepared statement.
|
||||
*
|
||||
* @param stmt Pointer to the statement pointer.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/finalize.html](http://www.sqlite.org/c3ref/finalize.html)
|
||||
*/
|
||||
abstract fun finalize(stmt: Long): Int
|
||||
|
||||
/**
|
||||
* Evaluates a statement.
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/step.html](http://www.sqlite.org/c3ref/step.html)
|
||||
*/
|
||||
abstract fun step(stmt: Long): Int
|
||||
|
||||
/**
|
||||
* Sets a prepared statement object back to its initial state, ready to be re-executed.
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/reset.html](http://www.sqlite.org/c3ref/reset.html)
|
||||
*/
|
||||
abstract fun reset(stmt: Long): Int
|
||||
|
||||
/**
|
||||
* Reset all bindings on a prepared statement (reset all host parameters to NULL).
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/clear_bindings.html](http://www.sqlite.org/c3ref/clear_bindings.html)
|
||||
*/
|
||||
abstract fun clear_bindings(stmt: Long): Int
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return Number of parameters in a prepared SQL.
|
||||
* @see [http://www.sqlite.org/c3ref/bind_parameter_count.html](http://www.sqlite.org/c3ref/bind_parameter_count.html)
|
||||
*/
|
||||
abstract fun bind_parameter_count(stmt: Long): Int
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return Number of columns in the result set returned by the prepared statement.
|
||||
* @see [http://www.sqlite.org/c3ref/column_count.html](http://www.sqlite.org/c3ref/column_count.html)
|
||||
*/
|
||||
abstract fun column_count(stmt: Long): Int
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @param col Number of column.
|
||||
* @return Datatype code for the initial data type of the result column.
|
||||
* @see [http://www.sqlite.org/c3ref/column_blob.html](http://www.sqlite.org/c3ref/column_blob.html)
|
||||
*/
|
||||
abstract fun column_type(stmt: Long, col: Int): Int
|
||||
abstract fun column_text(statementPointer: Long, zeroBasedColumnIndex: Int): String?
|
||||
abstract fun column_blob(statementPointer: Long, zeroBasedColumnIndex: Int): ByteArray?
|
||||
abstract fun column_double(statementPointer: Long, zeroBasedColumnIndex: Int): Double
|
||||
abstract fun column_long(statementPointer: Long, zeroBasedColumnIndex: Int): Long
|
||||
abstract fun column_int(statementPointer: Long, zeroBasedColumnIndex: Int): Int
|
||||
abstract fun bind_null(stmt: Long, oneBasedColumnIndex: Int): Int
|
||||
abstract fun bind_int(stmt: Long, oneBasedColumnIndex: Int, v: Int): Int
|
||||
abstract fun bind_long(stmt: Long, oneBasedColumnIndex: Int, v: Long): Int
|
||||
abstract fun bind_double(stmt: Long, oneBasedColumnIndex: Int, v: Double): Int
|
||||
abstract fun bind_text(stmt: Long, oneBasedColumnIndex: Int, v: String?): Int
|
||||
abstract fun bind_blob(stmt: Long, oneBasedColumnIndex: Int, v: ByteArray?): Int
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as NULL with the pointer to the SQLite database context.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_null(context: Long)
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as text data type with the pointer to the SQLite database
|
||||
* context and the the result value of String.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_text(context: Long, `val`: String?)
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as blob data type with the pointer to the SQLite database
|
||||
* context and the the result value of byte array.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_blob(context: Long, `val`: ByteArray?)
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as double data type with the pointer to the SQLite
|
||||
* database context and the the result value of double.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_double(context: Long, `val`: Double)
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as long data type with the pointer to the SQLite database
|
||||
* context and the the result value of long.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_long(context: Long, `val`: Long)
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as int data type with the pointer to the SQLite database
|
||||
* context and the the result value of int.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_int(context: Long, `val`: Int)
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as an error with the pointer to the SQLite database
|
||||
* context and the error of String.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param err Error result of an SQL function.
|
||||
* @see [http://www.sqlite.org/c3ref/result_blob.html](http://www.sqlite.org/c3ref/result_blob.html)
|
||||
*/
|
||||
abstract fun result_error(context: Long, err: String?)
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in text data type.
|
||||
* @see [http://www.sqlite.org/c3ref/value_blob.html](http://www.sqlite.org/c3ref/value_blob.html)
|
||||
*/
|
||||
abstract fun value_text(f: Function, arg: Int): String
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in blob data type.
|
||||
* @see [http://www.sqlite.org/c3ref/value_blob.html](http://www.sqlite.org/c3ref/value_blob.html)
|
||||
*/
|
||||
abstract fun value_blob(f: Function?, arg: Int): ByteArray?
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in double data type
|
||||
* @see [http://www.sqlite.org/c3ref/value_blob.html](http://www.sqlite.org/c3ref/value_blob.html)
|
||||
*/
|
||||
abstract fun value_double(f: Function?, arg: Int): Double
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in long data type.
|
||||
* @see [http://www.sqlite.org/c3ref/value_blob.html](http://www.sqlite.org/c3ref/value_blob.html)
|
||||
*/
|
||||
abstract fun value_long(f: Function?, arg: Int): Long
|
||||
|
||||
/**
|
||||
* Accesses the parameter values on the function or aggregate in int data type with the function
|
||||
* object and the parameter value.
|
||||
*
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate.
|
||||
* @see [http://www.sqlite.org/c3ref/value_blob.html](http://www.sqlite.org/c3ref/value_blob.html)
|
||||
*/
|
||||
abstract fun value_int(f: Function?, arg: Int): Int
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter datatype of the function or aggregate in int data type.
|
||||
* @see [http://www.sqlite.org/c3ref/value_blob.html](http://www.sqlite.org/c3ref/value_blob.html)
|
||||
*/
|
||||
abstract fun value_type(f: Function, arg: Int): Int
|
||||
|
||||
/**
|
||||
* Create a user defined function with given function name and the function object.
|
||||
*
|
||||
* @param name The function name to be created.
|
||||
* @param function SQLite function object.
|
||||
* @param flags Extra flags to use when creating the function, such as [ ][Function.FLAG_DETERMINISTIC]
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [http://www.sqlite.org/c3ref/create_function.html](http://www.sqlite.org/c3ref/create_function.html)
|
||||
*/
|
||||
abstract fun create_function(name: String, function: Function, nArgs: Int, flags: Int): Int
|
||||
|
||||
/**
|
||||
* De-registers a user defined function
|
||||
*
|
||||
* @param name Name of the function to de-register.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
abstract fun destroy_function(name: String): Int
|
||||
|
||||
/**
|
||||
* Create a user defined collation with given collation name and the collation object.
|
||||
*
|
||||
* @param name The collation name to be created.
|
||||
* @param collation SQLite collation object.
|
||||
* @return [Result Codes](https://www.sqlite.org/c3ref/c_abort.html)
|
||||
* @see [https://www.sqlite.org/c3ref/create_collation.html](https://www.sqlite.org/c3ref/create_collation.html)
|
||||
*/
|
||||
abstract fun create_collation(name: String, collation: Collation): Int
|
||||
|
||||
/**
|
||||
* Create a user defined collation with given collation name and the collation object.
|
||||
*
|
||||
* @param name The collation name to be created.
|
||||
* @return [Result Codes](https://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
abstract fun destroy_collation(name: String): Int
|
||||
|
||||
/**
|
||||
* @param dbName Database name to be backed up.
|
||||
* @param destFileName Target backup file name.
|
||||
* @param observer ProgressObserver object.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
abstract fun backup(dbName: String, destFileName: String, observer: ProgressObserver?): Int
|
||||
|
||||
/**
|
||||
* @param dbName Database name to be backed up.
|
||||
* @param destFileName Target backup file name.
|
||||
* @param observer ProgressObserver object.
|
||||
* @param sleepTimeMillis time to wait during a backup/restore operation if sqlite3_backup_step
|
||||
* returns SQLITE_BUSY before continuing
|
||||
* @param nTimeouts the number of times sqlite3_backup_step can return SQLITE_BUSY before
|
||||
* failing
|
||||
* @param pagesPerStep the number of pages to copy in each sqlite3_backup_step. If this is
|
||||
* negative, the entire DB is copied at once.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
abstract fun backup(dbName: String,
|
||||
destFileName: String,
|
||||
observer: ProgressObserver?,
|
||||
sleepTimeMillis: Int,
|
||||
nTimeouts: Int,
|
||||
pagesPerStep: Int): Int
|
||||
|
||||
/**
|
||||
* @param dbName Database name for restoring data.
|
||||
* @param sourceFileName Source file name.
|
||||
* @param observer ProgressObserver object.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
abstract fun restore(dbName: String, sourceFileName: String, observer: ProgressObserver?): Int
|
||||
|
||||
/**
|
||||
* @param dbName the name of the db to restore
|
||||
* @param sourceFileName the filename of the source db to restore
|
||||
* @param observer ProgressObserver object.
|
||||
* @param sleepTimeMillis time to wait during a backup/restore operation if sqlite3_backup_step
|
||||
* returns SQLITE_BUSY before continuing
|
||||
* @param nTimeouts the number of times sqlite3_backup_step can return SQLITE_BUSY before
|
||||
* failing
|
||||
* @param pagesPerStep the number of pages to copy in each sqlite3_backup_step. If this is
|
||||
* negative, the entire DB is copied at once.
|
||||
* @return [Result Codes](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
abstract fun restore(dbName: String?,
|
||||
sourceFileName: String?,
|
||||
observer: ProgressObserver?,
|
||||
sleepTimeMillis: Int,
|
||||
nTimeouts: Int,
|
||||
pagesPerStep: Int): Int
|
||||
|
||||
/**
|
||||
* @param id The id of the limit.
|
||||
* @param value The new value of the limit.
|
||||
* @return The prior value of the limit
|
||||
* @see [https://www.sqlite.org/c3ref/limit.html](https://www.sqlite.org/c3ref/limit.html)
|
||||
*/
|
||||
abstract fun limit(id: Int, value: Int): Int
|
||||
|
||||
// COMPOUND FUNCTIONS ////////////////////////////////////////////
|
||||
abstract fun set_commit_listener(enabled: Boolean)
|
||||
|
||||
abstract fun set_update_listener(enabled: Boolean)
|
||||
|
||||
@Synchronized
|
||||
fun addUpdateListener(listener: SQLiteUpdateListener) {
|
||||
if (updateListeners.add(listener) && updateListeners.size == 1) {
|
||||
set_update_listener(true)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun addCommitListener(listener: SQLiteCommitListener) {
|
||||
if (commitListeners.add(listener) && commitListeners.size == 1) {
|
||||
set_commit_listener(true)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun removeUpdateListener(listener: SQLiteUpdateListener) {
|
||||
if (updateListeners.remove(listener) && updateListeners.isEmpty()) {
|
||||
set_update_listener(false)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun removeCommitListener(listener: SQLiteCommitListener) {
|
||||
if (commitListeners.remove(listener) && commitListeners.isEmpty()) {
|
||||
set_commit_listener(false)
|
||||
}
|
||||
}
|
||||
|
||||
fun onUpdate(type: Int, database: String?, table: String?, rowId: Long) {
|
||||
var listeners: Set<SQLiteUpdateListener>
|
||||
synchronized(this) { listeners = HashSet(updateListeners) }
|
||||
for (listener in listeners) {
|
||||
val operationType = when (type) {
|
||||
18 -> SQLiteUpdateListener.Type.INSERT
|
||||
9 -> SQLiteUpdateListener.Type.DELETE
|
||||
23 -> SQLiteUpdateListener.Type.UPDATE
|
||||
else -> throw AssertionError("Unknown type: $type")
|
||||
}
|
||||
listener.onUpdate(operationType, database, table, rowId)
|
||||
}
|
||||
}
|
||||
|
||||
fun onCommit(commit: Boolean) {
|
||||
var listeners: Set<SQLiteCommitListener>
|
||||
synchronized(this) { listeners = HashSet(commitListeners) }
|
||||
for (listener in listeners) {
|
||||
if (commit) {
|
||||
listener.onCommit()
|
||||
}
|
||||
else {
|
||||
listener.onRollback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws IOException with an error message.
|
||||
*/
|
||||
@Suppress("unused", "SpellCheckingInspection")
|
||||
@Throws(IOException::class)
|
||||
fun throwex() {
|
||||
throw IOException(errmsg())
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection", "unused")
|
||||
fun throwex(errorCode: Int) {
|
||||
throw newException(errorCode = errorCode, errorMessage = errmsg()!!)
|
||||
}
|
||||
|
||||
fun newException(errorCode: Int, sql: String? = null): SqliteException {
|
||||
return newException(errorCode = errorCode, errorMessage = errmsg()!!, sql = sql)
|
||||
}
|
||||
|
||||
interface ProgressObserver {
|
||||
fun progress(remaining: Int, pageCount: Int)
|
||||
}
|
||||
}
|
||||
|
||||
class SqliteException internal constructor(message: String, @Suppress("unused") val resultCode: SqliteErrorCode) : IOException(message)
|
||||
|
||||
// https://www.sqlite.org/c3ref/commit_hook.html)
|
||||
interface SQLiteCommitListener {
|
||||
fun onCommit()
|
||||
fun onRollback()
|
||||
}
|
||||
|
||||
/** [...](https://www.sqlite.org/c3ref/update_hook.html) */
|
||||
interface SQLiteUpdateListener {
|
||||
fun onUpdate(type: Type?, database: String?, table: String?, rowId: Long)
|
||||
enum class Type {
|
||||
INSERT,
|
||||
DELETE,
|
||||
UPDATE
|
||||
}
|
||||
}
|
||||
|
||||
internal object SqliteCodes {
|
||||
/** Successful result */
|
||||
const val SQLITE_OK = 0
|
||||
|
||||
/** Library used incorrectly */
|
||||
const val SQLITE_MISUSE = 21
|
||||
|
||||
/** sqlite_step() has another row ready */
|
||||
const val SQLITE_ROW = 100
|
||||
|
||||
/** sqlite_step() has finished executing */
|
||||
const val SQLITE_DONE = 101
|
||||
}
|
||||
@@ -22,18 +22,18 @@
|
||||
// $URL$
|
||||
// $Author$
|
||||
// --------------------------------------
|
||||
package org.jetbrains.sqlite;
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
/**
|
||||
* SQLite3 error code
|
||||
*
|
||||
* @author leo
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/c_abort.html">http://www.sqlite.org/c3ref/c_abort.html</a>
|
||||
* @see [http://www.sqlite.org/c3ref/c_abort.html](http://www.sqlite.org/c3ref/c_abort.html)
|
||||
*/
|
||||
public enum SQLiteErrorCode {
|
||||
enum class SqliteErrorCode(@JvmField val code: Int, @JvmField val message: String) {
|
||||
UNKNOWN_ERROR(-1, "unknown error"),
|
||||
SQLITE_OK(0, "Successful result"),
|
||||
|
||||
/* beginning-of-error-codes */
|
||||
SQLITE_ERROR(1, "SQL error or missing database"),
|
||||
SQLITE_INTERNAL(2, "Internal logic error in SQLite"),
|
||||
@@ -65,6 +65,7 @@ public enum SQLiteErrorCode {
|
||||
SQLITE_WARNING(28, "Warnings from sqlite3_log()"),
|
||||
SQLITE_ROW(100, "sqlite3_step() has another row ready"),
|
||||
SQLITE_DONE(101, "sqlite3_step() has finished executing"),
|
||||
|
||||
/* Beginning of extended error codes */
|
||||
SQLITE_ABORT_ROLLBACK(
|
||||
516,
|
||||
@@ -184,34 +185,17 @@ public enum SQLiteErrorCode {
|
||||
SQLITE_READONLY_ROLLBACK(776, "Hot journal needs to be rolled back"),
|
||||
SQLITE_WARNING_AUTOINDEX(284, "automatic indexing is used");
|
||||
|
||||
public final int code;
|
||||
public final String message;
|
||||
|
||||
/**
|
||||
* Constructor that applies error code and message.
|
||||
*
|
||||
* @param code Error code.
|
||||
* @param message Message for the error.
|
||||
/** @see Enum.toString
|
||||
*/
|
||||
SQLiteErrorCode(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
override fun toString(): String = "[$name] $message"
|
||||
|
||||
/** @see Enum#toString() */
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[%s] %s", name(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param errorCode Error code.
|
||||
* @return Error message.
|
||||
*/
|
||||
public static SQLiteErrorCode getErrorCode(int errorCode) {
|
||||
for (SQLiteErrorCode each : values()) {
|
||||
if (errorCode == each.code) return each;
|
||||
companion object {
|
||||
/**
|
||||
* @param errorCode Error code.
|
||||
* @return Error message.
|
||||
*/
|
||||
internal fun getErrorCode(errorCode: Int): SqliteErrorCode {
|
||||
return values().firstOrNull { errorCode == it.code } ?: UNKNOWN_ERROR
|
||||
}
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite.core
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
class SqliteIntPreparedStatement internal constructor(private val connection: SqliteConnection, private val sql: String) : SqliteStatement {
|
||||
@JvmField
|
||||
internal val pointer: SafeStatementPointer
|
||||
private val pointer: SafeStatementPointer
|
||||
|
||||
private var batchPosition = 0
|
||||
private var batch: IntArray
|
||||
@@ -36,17 +35,14 @@ class SqliteIntPreparedStatement internal constructor(private val connection: Sq
|
||||
isClosed = true
|
||||
}
|
||||
|
||||
internal val db: DB
|
||||
get() = connection.db
|
||||
|
||||
private fun internalClose() {
|
||||
val pointer = pointer.takeIf { !it.isClosed } ?: return
|
||||
check(!connection.isClosed) { "Connection is closed" }
|
||||
|
||||
batchPosition = 0
|
||||
val status = pointer.close()
|
||||
if (status != Codes.SQLITE_OK && status != Codes.SQLITE_MISUSE) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK && status != SqliteCodes.SQLITE_MISUSE) {
|
||||
throw connection.db.newException(status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,14 +65,15 @@ class SqliteIntPreparedStatement internal constructor(private val connection: Sq
|
||||
}
|
||||
|
||||
try {
|
||||
synchronized(pointer.db) {
|
||||
val db = connection.db
|
||||
synchronized(db) {
|
||||
pointer.ensureOpen()
|
||||
for (batchIndex in 0 until batchQueryCount) {
|
||||
db.reset(pointer.pointer)
|
||||
for (position in 0 until paramCount) {
|
||||
val status = db.bind_int(pointer.pointer, position + 1, batch[batchIndex * paramCount + position]) and 0xFF
|
||||
if (status != Codes.SQLITE_OK) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite.core
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import org.jetbrains.sqlite.Binder
|
||||
import kotlin.time.Duration
|
||||
|
||||
class SqlitePreparedStatement<T : Binder> internal constructor(private val connection: SqliteConnection,
|
||||
@@ -37,7 +36,7 @@ class SqlitePreparedStatement<T : Binder> internal constructor(private val conne
|
||||
isClosed = true
|
||||
}
|
||||
|
||||
internal val db: DB
|
||||
internal val db: SqliteDb
|
||||
get() = connection.db
|
||||
|
||||
private fun internalClose() {
|
||||
@@ -47,8 +46,8 @@ class SqlitePreparedStatement<T : Binder> internal constructor(private val conne
|
||||
resultSet.close()
|
||||
binder.clearBatch()
|
||||
val status = pointer.close()
|
||||
if (status != Codes.SQLITE_OK && status != Codes.SQLITE_MISUSE) {
|
||||
throw db.newSQLException(status)
|
||||
if (status != SqliteCodes.SQLITE_OK && status != SqliteCodes.SQLITE_MISUSE) {
|
||||
throw db.newException(status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite.core
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
private const val SQLITE_NULL = 5
|
||||
|
||||
class SqliteResultSet(private val statement: SqlitePreparedStatement<*>) {
|
||||
/**
|
||||
@@ -58,16 +60,16 @@ class SqliteResultSet(private val statement: SqlitePreparedStatement<*>) {
|
||||
}
|
||||
|
||||
// do the real work
|
||||
return when (val statusCode = statement.pointer.safeRunInt(DB::step)) {
|
||||
Codes.SQLITE_DONE -> {
|
||||
return when (val statusCode = statement.pointer.safeRunInt(SqliteDb::step)) {
|
||||
SqliteCodes.SQLITE_DONE -> {
|
||||
pastLastRow = true
|
||||
false
|
||||
}
|
||||
Codes.SQLITE_ROW -> {
|
||||
SqliteCodes.SQLITE_ROW -> {
|
||||
row++
|
||||
true
|
||||
}
|
||||
else -> throw statement.db.newSQLException(statusCode)
|
||||
else -> throw statement.db.newException(statusCode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +88,7 @@ class SqliteResultSet(private val statement: SqlitePreparedStatement<*>) {
|
||||
//val isFirst: Boolean
|
||||
// get() = row == 1
|
||||
|
||||
fun wasNull(): Boolean = safeGetColumnType(lastColumn) == Codes.SQLITE_NULL
|
||||
fun wasNull(): Boolean = safeGetColumnType(lastColumn) == SQLITE_NULL
|
||||
|
||||
///** @see ResultSet.getBigDecimal
|
||||
// */
|
||||
@@ -122,11 +124,11 @@ class SqliteResultSet(private val statement: SqlitePreparedStatement<*>) {
|
||||
}
|
||||
|
||||
fun getDouble(col: Int): Double {
|
||||
return if (safeGetColumnType(markColumn(col)) == Codes.SQLITE_NULL) 0.0 else safeGetDoubleCol(col)
|
||||
return if (safeGetColumnType(markColumn(col)) == SQLITE_NULL) 0.0 else safeGetDoubleCol(col)
|
||||
}
|
||||
|
||||
fun getFloat(col: Int): Float {
|
||||
return if (safeGetColumnType(markColumn(col)) == Codes.SQLITE_NULL) 0f else safeGetDoubleCol(col).toFloat()
|
||||
return if (safeGetColumnType(markColumn(col)) == SQLITE_NULL) 0f else safeGetDoubleCol(col).toFloat()
|
||||
}
|
||||
|
||||
fun getInt(zeroBasedColumnIndex: Int): Int {
|
||||
@@ -137,9 +139,9 @@ class SqliteResultSet(private val statement: SqlitePreparedStatement<*>) {
|
||||
|
||||
fun getLong(zeroBasedColumnIndex: Int): Long {
|
||||
val pointer = statement.pointer
|
||||
synchronized(pointer.db) {
|
||||
synchronized(statement.db) {
|
||||
pointer.ensureOpen()
|
||||
return pointer.db.column_long(pointer.pointer, markColumn(zeroBasedColumnIndex))
|
||||
return statement.db.column_long(pointer.pointer, markColumn(zeroBasedColumnIndex))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,9 +153,9 @@ class SqliteResultSet(private val statement: SqlitePreparedStatement<*>) {
|
||||
|
||||
private fun safeGetDoubleCol(zeroBasedColumnIndex: Int): Double {
|
||||
val pointer = statement.pointer
|
||||
synchronized(pointer.db) {
|
||||
synchronized(statement.db) {
|
||||
pointer.ensureOpen()
|
||||
return pointer.db.column_double(pointer.pointer, markColumn(zeroBasedColumnIndex))
|
||||
return statement.db.column_double(pointer.pointer, markColumn(zeroBasedColumnIndex))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite.core;
|
||||
package org.jetbrains.sqlite;
|
||||
|
||||
public final class SqliteSavepoint {
|
||||
final int id;
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite.core
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
sealed interface SqliteStatement : AutoCloseable {
|
||||
fun executeBatch()
|
||||
@@ -3,10 +3,6 @@ package org.jetbrains.sqlite
|
||||
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.sqlite.core.SqliteConnection
|
||||
import org.jetbrains.sqlite.core.SqliteIntPreparedStatement
|
||||
import org.jetbrains.sqlite.core.SqlitePreparedStatement
|
||||
import org.jetbrains.sqlite.core.SqliteStatement
|
||||
|
||||
/**
|
||||
* Simplifies calling [SqliteStatement.executeBatch] or [SqliteStatement.close] for multiple statements.
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
package org.jetbrains.sqlite.core;
|
||||
|
||||
public interface Codes {
|
||||
/** Successful result */
|
||||
int SQLITE_OK = 0;
|
||||
|
||||
/** SQL error or missing database */
|
||||
int SQLITE_ERROR = 1;
|
||||
|
||||
/** An internal logic error in SQLite */
|
||||
int SQLITE_INTERNAL = 2;
|
||||
|
||||
/** Access permission denied */
|
||||
int SQLITE_PERM = 3;
|
||||
|
||||
/** Callback routine requested an abort */
|
||||
int SQLITE_ABORT = 4;
|
||||
|
||||
/** The database file is locked */
|
||||
int SQLITE_BUSY = 5;
|
||||
|
||||
/** A table in the database is locked */
|
||||
int SQLITE_LOCKED = 6;
|
||||
|
||||
/** A malloc() failed */
|
||||
int SQLITE_NOMEM = 7;
|
||||
|
||||
/** Attempt to write a readonly database */
|
||||
int SQLITE_READONLY = 8;
|
||||
|
||||
/** Operation terminated by sqlite_interrupt() */
|
||||
int SQLITE_INTERRUPT = 9;
|
||||
|
||||
/** Some kind of disk I/O error occurred */
|
||||
int SQLITE_IOERR = 10;
|
||||
|
||||
/** The database disk image is malformed */
|
||||
int SQLITE_CORRUPT = 11;
|
||||
|
||||
/** (Internal Only) Table or record not found */
|
||||
int SQLITE_NOTFOUND = 12;
|
||||
|
||||
/** Insertion failed because database is full */
|
||||
int SQLITE_FULL = 13;
|
||||
|
||||
/** Unable to open the database file */
|
||||
int SQLITE_CANTOPEN = 14;
|
||||
|
||||
/** Database lock protocol error */
|
||||
int SQLITE_PROTOCOL = 15;
|
||||
|
||||
/** (Internal Only) Database table is empty */
|
||||
int SQLITE_EMPTY = 16;
|
||||
|
||||
/** The database schema changed */
|
||||
int SQLITE_SCHEMA = 17;
|
||||
|
||||
/** Too much data for one row of a table */
|
||||
int SQLITE_TOOBIG = 18;
|
||||
|
||||
/** Abort due to constraint violation */
|
||||
int SQLITE_CONSTRAINT = 19;
|
||||
|
||||
/** Data type mismatch */
|
||||
int SQLITE_MISMATCH = 20;
|
||||
|
||||
/** Library used incorrectly */
|
||||
int SQLITE_MISUSE = 21;
|
||||
|
||||
/** Uses OS features not supported on host */
|
||||
int SQLITE_NOLFS = 22;
|
||||
|
||||
/** Authorization denied */
|
||||
int SQLITE_AUTH = 23;
|
||||
|
||||
/** sqlite_step() has another row ready */
|
||||
int SQLITE_ROW = 100;
|
||||
|
||||
/** sqlite_step() has finished executing */
|
||||
int SQLITE_DONE = 101;
|
||||
|
||||
// types returned by sqlite3_column_type()
|
||||
|
||||
int SQLITE_INTEGER = 1;
|
||||
int SQLITE_FLOAT = 2;
|
||||
int SQLITE_TEXT = 3;
|
||||
int SQLITE_BLOB = 4;
|
||||
int SQLITE_NULL = 5;
|
||||
}
|
||||
@@ -1,730 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
package org.jetbrains.sqlite.core;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.sqlite.*;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/*
|
||||
* This class is the interface to SQLite. It provides some helper functions
|
||||
* used by other parts of the driver. The goal of the helper functions here
|
||||
* are not only to provide functionality, but to handle contractual
|
||||
* differences between the JDBC specification and the SQLite C API.
|
||||
*
|
||||
* The process of moving SQLite weirdness into this class is incomplete.
|
||||
* You'll still find lots of code in Stmt and PrepStmt that are doing
|
||||
* implicit contract conversions. Sorry.
|
||||
*
|
||||
* The subclass, NativeDB, provides the actual access to SQLite functions.
|
||||
*/
|
||||
public abstract class DB implements Codes {
|
||||
private final AtomicBoolean closed = new AtomicBoolean(true);
|
||||
// tracer for statements to avoid unfinalized statements on db close
|
||||
private final Set<SafeStatementPointer> statements = ConcurrentHashMap.newKeySet();
|
||||
private final Set<SQLiteUpdateListener> updateListeners = new HashSet<>();
|
||||
private final Set<SQLiteCommitListener> commitListeners = new HashSet<>();
|
||||
|
||||
public DB() {
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed.get();
|
||||
}
|
||||
|
||||
// WRAPPER FUNCTIONS ////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Aborts any pending operation and returns at its earliest opportunity.
|
||||
*
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/interrupt.html">http://www.sqlite.org/c3ref/interrupt.html</a>
|
||||
*/
|
||||
public abstract void interrupt();
|
||||
|
||||
/**
|
||||
* Sets a <a href="http://www.sqlite.org/c3ref/busy_handler.html">busy handler</a> that sleeps
|
||||
* for a specified amount of time when a table is locked.
|
||||
*
|
||||
* @param ms Time to sleep in milliseconds.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/busy_timeout.html">http://www.sqlite.org/c3ref/busy_timeout.html</a>
|
||||
*/
|
||||
public abstract void busy_timeout(int ms);
|
||||
|
||||
/**
|
||||
* Sets a <a href="http://www.sqlite.org/c3ref/busy_handler.html">busy handler</a> that sleeps
|
||||
* for a specified amount of time when a table is locked.
|
||||
*
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/busy_handler.html">http://www.sqlite.org/c3ref/busy_timeout.html</a>
|
||||
*/
|
||||
public abstract void busy_handler(BusyHandler busyHandler);
|
||||
|
||||
/**
|
||||
* Return English-language text that describes the error as either UTF-8 or UTF-16.
|
||||
*
|
||||
* @return Error description in English.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/errcode.html">http://www.sqlite.org/c3ref/errcode.html</a>
|
||||
*/
|
||||
abstract String errmsg();
|
||||
|
||||
/**
|
||||
* Returns the value for SQLITE_VERSION, SQLITE_VERSION_NUMBER, and SQLITE_SOURCE_ID C
|
||||
* preprocessor macros that are associated with the library.
|
||||
*
|
||||
* @return Compile-time SQLite version information.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/libversion.html">http://www.sqlite.org/c3ref/libversion.html</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/c_source_id.html">http://www.sqlite.org/c3ref/c_source_id.html</a>
|
||||
*/
|
||||
public abstract String libversion();
|
||||
|
||||
/**
|
||||
* @return Number of rows that were changed, inserted or deleted by the last SQL statement
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/changes.html">http://www.sqlite.org/c3ref/changes.html</a>
|
||||
*/
|
||||
public abstract long changes();
|
||||
|
||||
/**
|
||||
* @return Number of row changes caused by INSERT, UPDATE or DELETE statements since the
|
||||
* database connection was opened.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/total_changes.html">http://www.sqlite.org/c3ref/total_changes.html</a>
|
||||
*/
|
||||
public abstract long total_changes();
|
||||
|
||||
public abstract int shared_cache(boolean enable);
|
||||
|
||||
/**
|
||||
* Enables or disables loading of SQLite extensions.
|
||||
*
|
||||
* @param enable True to enable; false otherwise.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/load_extension.html">http://www.sqlite.org/c3ref/load_extension.html</a>
|
||||
*/
|
||||
public abstract int enable_load_extension(boolean enable);
|
||||
|
||||
/**
|
||||
* Execute an SQL statement using the process of compiling, evaluating, and destroying the prepared statement object.
|
||||
*
|
||||
* @param sql SQL statement to be executed.
|
||||
* @see <a href="http://www.sqlite.org/c3ref/exec.html">http://www.sqlite.org/c3ref/exec.html</a>
|
||||
*/
|
||||
public final synchronized void exec(@NotNull String sql) throws SQLException {
|
||||
int status = _exec(sql);
|
||||
if (status != SQLITE_OK) {
|
||||
throw newSQLException(status, errmsg(), sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an SQLite interface to a database for the given connection.
|
||||
*
|
||||
* @param file The database.
|
||||
* @param openFlags File opening configurations (<a
|
||||
* href="http://www.sqlite.org/c3ref/c_open_autoproxy.html">http://www.sqlite.org/c3ref/c_open_autoproxy.html</a>)
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/open.html">http://www.sqlite.org/c3ref/open.html</a>
|
||||
*/
|
||||
final synchronized void open(String file, int openFlags) throws SQLException {
|
||||
_open(file, openFlags);
|
||||
closed.set(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a database connection and finalizes any remaining statements before the closing
|
||||
* operation.
|
||||
*
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/close.html">http://www.sqlite.org/c3ref/close.html</a>
|
||||
*/
|
||||
public final synchronized void close() throws SQLException {
|
||||
// finalize any remaining statements before closing db
|
||||
for (SafeStatementPointer element : statements) {
|
||||
try {
|
||||
element.internalClose$intellij_platform_sqlite();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
Logger.getInstance(DB.class).error(e);
|
||||
}
|
||||
}
|
||||
|
||||
closed.set(true);
|
||||
_close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Complies an SQL statement.
|
||||
* @see <a href="http://www.sqlite.org/c3ref/prepare.html">http://www.sqlite.org/c3ref/prepare.html</a>
|
||||
*/
|
||||
final synchronized @NotNull SafeStatementPointer prepareForStatement(@NotNull String sql) throws SQLException {
|
||||
SafeStatementPointer pointer = prepare(sql);
|
||||
if (!statements.add(pointer)) {
|
||||
throw new IllegalStateException("Already added pointer to statements set");
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a statement.
|
||||
*
|
||||
* @param safePtr the pointer wrapper to remove from internal structures
|
||||
* @param ptr the raw pointer to free
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/finalize.html">http://www.sqlite.org/c3ref/finalize.html</a>
|
||||
*/
|
||||
public synchronized int finalize(SafeStatementPointer safePtr, long ptr) {
|
||||
try {
|
||||
return finalize(ptr);
|
||||
}
|
||||
finally {
|
||||
statements.remove(safePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an SQLite interface to a database with the provided open flags.
|
||||
*
|
||||
* @param filename The database to open.
|
||||
* @param openFlags File opening configurations (<a
|
||||
* href="http://www.sqlite.org/c3ref/c_open_autoproxy.html">http://www.sqlite.org/c3ref/c_open_autoproxy.html</a>)
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/open.html">http://www.sqlite.org/c3ref/open.html</a>
|
||||
*/
|
||||
protected abstract void _open(String filename, int openFlags) throws SQLException;
|
||||
|
||||
/**
|
||||
* Closes the SQLite interface to a database.
|
||||
*
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/close.html">http://www.sqlite.org/c3ref/close.html</a>
|
||||
*/
|
||||
protected abstract void _close() throws SQLException;
|
||||
|
||||
/**
|
||||
* Complies, evaluates, executes and commits an SQL statement.
|
||||
*
|
||||
* @param sql An SQL statement.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/exec.html">http://www.sqlite.org/c3ref/exec.html</a>
|
||||
*/
|
||||
public abstract int _exec(String sql) throws SQLException;
|
||||
|
||||
/**
|
||||
* Complies an SQL statement.
|
||||
*
|
||||
* @param sql An SQL statement.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/prepare.html">http://www.sqlite.org/c3ref/prepare.html</a>
|
||||
*/
|
||||
protected abstract SafeStatementPointer prepare(String sql) throws SQLException;
|
||||
|
||||
/**
|
||||
* Destroys a prepared statement.
|
||||
*
|
||||
* @param stmt Pointer to the statement pointer.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/finalize.html">http://www.sqlite.org/c3ref/finalize.html</a>
|
||||
*/
|
||||
public abstract int finalize(long stmt);
|
||||
|
||||
/**
|
||||
* Evaluates a statement.
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/step.html">http://www.sqlite.org/c3ref/step.html</a>
|
||||
*/
|
||||
public abstract int step(long stmt);
|
||||
|
||||
/**
|
||||
* Sets a prepared statement object back to its initial state, ready to be re-executed.
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/reset.html">http://www.sqlite.org/c3ref/reset.html</a>
|
||||
*/
|
||||
public abstract int reset(long stmt);
|
||||
|
||||
/**
|
||||
* Reset all bindings on a prepared statement (reset all host parameters to NULL).
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/clear_bindings.html">http://www.sqlite.org/c3ref/clear_bindings.html</a>
|
||||
*/
|
||||
public abstract int clear_bindings(long stmt); // TODO remove?
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return Number of parameters in a prepared SQL.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/bind_parameter_count.html">http://www.sqlite.org/c3ref/bind_parameter_count.html</a>
|
||||
*/
|
||||
public abstract int bind_parameter_count(long stmt);
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return Number of columns in the result set returned by the prepared statement.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/column_count.html">http://www.sqlite.org/c3ref/column_count.html</a>
|
||||
*/
|
||||
public abstract int column_count(long stmt);
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @param col Number of column.
|
||||
* @return Datatype code for the initial data type of the result column.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/column_blob.html">http://www.sqlite.org/c3ref/column_blob.html</a>
|
||||
*/
|
||||
public abstract int column_type(long stmt, int col);
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @param col Number of column.
|
||||
* @return Declared type of the table column for prepared statement.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/column_decltype.html">http://www.sqlite.org/c3ref/column_decltype.html</a>
|
||||
*/
|
||||
public abstract String column_decltype(long stmt, int col);
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @param col Number of column.
|
||||
* @return Original text of column name which is the declared in the CREATE TABLE statement.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/column_database_name.html">http://www.sqlite.org/c3ref/column_database_name.html</a>
|
||||
*/
|
||||
public abstract String column_table_name(long stmt, int col);
|
||||
|
||||
/**
|
||||
* @param stmt Pointer to the statement.
|
||||
* @param col The number of column.
|
||||
* @return Name assigned to a particular column in the result set of a SELECT statement.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/column_name.html">http://www.sqlite.org/c3ref/column_name.html</a>
|
||||
*/
|
||||
public abstract String column_name(long stmt, int col);
|
||||
|
||||
public abstract String column_text(long statementPointer, int zeroBasedColumnIndex);
|
||||
public abstract byte[] column_blob(long statementPointer, int zeroBasedColumnIndex);
|
||||
public abstract double column_double(long statementPointer, int zeroBasedColumnIndex);
|
||||
public abstract long column_long(long statementPointer, int zeroBasedColumnIndex);
|
||||
public abstract int column_int(long statementPointer, int zeroBasedColumnIndex);
|
||||
|
||||
abstract int bind_null(long stmt, int oneBasedColumnIndex);
|
||||
public abstract int bind_int(long stmt, int oneBasedColumnIndex, int v);
|
||||
public abstract int bind_long(long stmt, int oneBasedColumnIndex, long v);
|
||||
abstract int bind_double(long stmt, int oneBasedColumnIndex, double v);
|
||||
abstract int bind_text(long stmt, int oneBasedColumnIndex, String v);
|
||||
abstract int bind_blob(long stmt, int oneBasedColumnIndex, byte[] v);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as NULL with the pointer to the SQLite database context.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_null(long context);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as text data type with the pointer to the SQLite database
|
||||
* context and the the result value of String.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_text(long context, String val);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as blob data type with the pointer to the SQLite database
|
||||
* context and the the result value of byte array.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_blob(long context, byte[] val);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as double data type with the pointer to the SQLite
|
||||
* database context and the the result value of double.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_double(long context, double val);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as long data type with the pointer to the SQLite database
|
||||
* context and the the result value of long.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_long(long context, long val);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as int data type with the pointer to the SQLite database
|
||||
* context and the the result value of int.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param val Result value of an SQL function.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_int(long context, int val);
|
||||
|
||||
/**
|
||||
* Sets the result of an SQL function as an error with the pointer to the SQLite database
|
||||
* context and the the error of String.
|
||||
*
|
||||
* @param context Pointer to the SQLite database context.
|
||||
* @param err Error result of an SQL function.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/result_blob.html">http://www.sqlite.org/c3ref/result_blob.html</a>
|
||||
*/
|
||||
public abstract void result_error(long context, String err);
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in text data type.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/value_blob.html">http://www.sqlite.org/c3ref/value_blob.html</a>
|
||||
*/
|
||||
public abstract String value_text(Function f, int arg);
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in blob data type.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/value_blob.html">http://www.sqlite.org/c3ref/value_blob.html</a>
|
||||
*/
|
||||
public abstract byte[] value_blob(Function f, int arg);
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in double data type
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/value_blob.html">http://www.sqlite.org/c3ref/value_blob.html</a>
|
||||
*/
|
||||
public abstract double value_double(Function f, int arg);
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate in long data type.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/value_blob.html">http://www.sqlite.org/c3ref/value_blob.html</a>
|
||||
*/
|
||||
public abstract long value_long(Function f, int arg);
|
||||
|
||||
/**
|
||||
* Accesses the parameter values on the function or aggregate in int data type with the function
|
||||
* object and the parameter value.
|
||||
*
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter value of the given SQLite function or aggregate.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/value_blob.html">http://www.sqlite.org/c3ref/value_blob.html</a>
|
||||
*/
|
||||
public abstract int value_int(Function f, int arg);
|
||||
|
||||
/**
|
||||
* @param f SQLite function object.
|
||||
* @param arg Pointer to the parameter of the SQLite function or aggregate.
|
||||
* @return Parameter datatype of the function or aggregate in int data type.
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/value_blob.html">http://www.sqlite.org/c3ref/value_blob.html</a>
|
||||
*/
|
||||
public abstract int value_type(Function f, int arg);
|
||||
|
||||
/**
|
||||
* Create a user defined function with given function name and the function object.
|
||||
*
|
||||
* @param name The function name to be created.
|
||||
* @param f SQLite function object.
|
||||
* @param flags Extra flags to use when creating the function, such as {@link
|
||||
* Function#FLAG_DETERMINISTIC}
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="http://www.sqlite.org/c3ref/create_function.html">http://www.sqlite.org/c3ref/create_function.html</a>
|
||||
*/
|
||||
public abstract int create_function(String name, Function f, int nArgs, int flags)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* De-registers a user defined function
|
||||
*
|
||||
* @param name Name of the function to de-registered.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
*/
|
||||
public abstract int destroy_function(String name) throws SQLException;
|
||||
|
||||
/**
|
||||
* Create a user defined collation with given collation name and the collation object.
|
||||
*
|
||||
* @param name The collation name to be created.
|
||||
* @param c SQLite collation object.
|
||||
* @return <a href="https://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
* @see <a
|
||||
* href="https://www.sqlite.org/c3ref/create_collation.html">https://www.sqlite.org/c3ref/create_collation.html</a>
|
||||
*/
|
||||
public abstract int create_collation(String name, Collation c) throws SQLException;
|
||||
|
||||
/**
|
||||
* Create a user defined collation with given collation name and the collation object.
|
||||
*
|
||||
* @param name The collation name to be created.
|
||||
* @return <a href="https://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
*/
|
||||
public abstract int destroy_collation(String name) throws SQLException;
|
||||
|
||||
/**
|
||||
* @param dbName Database name to be backed up.
|
||||
* @param destFileName Target backup file name.
|
||||
* @param observer ProgressObserver object.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
*/
|
||||
public abstract int backup(String dbName, String destFileName, ProgressObserver observer)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* @param dbName Database name to be backed up.
|
||||
* @param destFileName Target backup file name.
|
||||
* @param observer ProgressObserver object.
|
||||
* @param sleepTimeMillis time to wait during a backup/restore operation if sqlite3_backup_step
|
||||
* returns SQLITE_BUSY before continuing
|
||||
* @param nTimeouts the number of times sqlite3_backup_step can return SQLITE_BUSY before
|
||||
* failing
|
||||
* @param pagesPerStep the number of pages to copy in each sqlite3_backup_step. If this is
|
||||
* negative, the entire DB is copied at once.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
*/
|
||||
public abstract int backup(
|
||||
String dbName,
|
||||
String destFileName,
|
||||
ProgressObserver observer,
|
||||
int sleepTimeMillis,
|
||||
int nTimeouts,
|
||||
int pagesPerStep)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* @param dbName Database name for restoring data.
|
||||
* @param sourceFileName Source file name.
|
||||
* @param observer ProgressObserver object.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
*/
|
||||
public abstract int restore(String dbName, String sourceFileName, ProgressObserver observer)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* @param dbName the name of the db to restore
|
||||
* @param sourceFileName the filename of the source db to restore
|
||||
* @param observer ProgressObserver object.
|
||||
* @param sleepTimeMillis time to wait during a backup/restore operation if sqlite3_backup_step
|
||||
* returns SQLITE_BUSY before continuing
|
||||
* @param nTimeouts the number of times sqlite3_backup_step can return SQLITE_BUSY before
|
||||
* failing
|
||||
* @param pagesPerStep the number of pages to copy in each sqlite3_backup_step. If this is
|
||||
* negative, the entire DB is copied at once.
|
||||
* @return <a href="http://www.sqlite.org/c3ref/c_abort.html">Result Codes</a>
|
||||
*/
|
||||
public abstract int restore(
|
||||
String dbName,
|
||||
String sourceFileName,
|
||||
ProgressObserver observer,
|
||||
int sleepTimeMillis,
|
||||
int nTimeouts,
|
||||
int pagesPerStep)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* @param id The id of the limit.
|
||||
* @param value The new value of the limit.
|
||||
* @return The prior value of the limit
|
||||
* @see <a
|
||||
* href="https://www.sqlite.org/c3ref/limit.html">https://www.sqlite.org/c3ref/limit.html</a>
|
||||
*/
|
||||
public abstract int limit(int id, int value) throws SQLException;
|
||||
|
||||
/** Progress handler */
|
||||
public abstract void register_progress_handler(int vmCalls, ProgressHandler progressHandler) throws SQLException
|
||||
;
|
||||
|
||||
public abstract void clear_progress_handler() throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns an array describing the attributes (not null, primary key and auto increment) of
|
||||
* columns.
|
||||
*
|
||||
* @param stmt Pointer to the statement.
|
||||
* @return Column attribute array.<br>
|
||||
* index[col][0] = true if column constrained NOT NULL;<br>
|
||||
* index[col][1] = true if column is part of the primary key; <br>
|
||||
* index[col][2] = true if column is auto-increment.
|
||||
*/
|
||||
public abstract boolean[][] column_metadata(long stmt);
|
||||
|
||||
// COMPOUND FUNCTIONS ////////////////////////////////////////////
|
||||
|
||||
abstract void set_commit_listener(boolean enabled);
|
||||
|
||||
abstract void set_update_listener(boolean enabled);
|
||||
|
||||
public synchronized void addUpdateListener(SQLiteUpdateListener listener) {
|
||||
if (updateListeners.add(listener) && updateListeners.size() == 1) {
|
||||
set_update_listener(true);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addCommitListener(SQLiteCommitListener listener) {
|
||||
if (commitListeners.add(listener) && commitListeners.size() == 1) {
|
||||
set_commit_listener(true);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeUpdateListener(SQLiteUpdateListener listener) {
|
||||
if (updateListeners.remove(listener) && updateListeners.isEmpty()) {
|
||||
set_update_listener(false);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeCommitListener(SQLiteCommitListener listener) {
|
||||
if (commitListeners.remove(listener) && commitListeners.isEmpty()) {
|
||||
set_commit_listener(false);
|
||||
}
|
||||
}
|
||||
|
||||
void onUpdate(int type, String database, String table, long rowId) {
|
||||
Set<SQLiteUpdateListener> listeners;
|
||||
|
||||
synchronized (this) {
|
||||
listeners = new HashSet<>(updateListeners);
|
||||
}
|
||||
|
||||
for (SQLiteUpdateListener listener : listeners) {
|
||||
SQLiteUpdateListener.Type operationType = switch (type) {
|
||||
case 18 -> SQLiteUpdateListener.Type.INSERT;
|
||||
case 9 -> SQLiteUpdateListener.Type.DELETE;
|
||||
case 23 -> SQLiteUpdateListener.Type.UPDATE;
|
||||
default -> throw new AssertionError("Unknown type: " + type);
|
||||
};
|
||||
|
||||
listener.onUpdate(operationType, database, table, rowId);
|
||||
}
|
||||
}
|
||||
|
||||
void onCommit(boolean commit) {
|
||||
Set<SQLiteCommitListener> listeners;
|
||||
|
||||
synchronized (this) {
|
||||
listeners = new HashSet<>(commitListeners);
|
||||
}
|
||||
|
||||
for (SQLiteCommitListener listener : listeners) {
|
||||
if (commit) {
|
||||
listener.onCommit();
|
||||
}
|
||||
else {
|
||||
listener.onRollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws SQLException with error message.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "SpellCheckingInspection"})
|
||||
final void throwex() throws SQLException {
|
||||
throw new SQLException(errmsg());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"SpellCheckingInspection", "unused"})
|
||||
public final void throwex(int errorCode) throws SQLException {
|
||||
throw newSQLException(errorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws SQL Exception with error code.
|
||||
*
|
||||
* @param errorCode Error code to be passed.
|
||||
* @return SQLException with error code and message.
|
||||
*/
|
||||
public final SQLiteException newSQLException(int errorCode) {
|
||||
return newSQLException(errorCode, errmsg(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws formatted SQLException with error code and message.
|
||||
*
|
||||
* @param errorCode Error code to be passed.
|
||||
* @param errorMessage Error message to be passed.
|
||||
* @return Formatted SQLException with error code and message.
|
||||
*/
|
||||
public static SQLiteException newSQLException(int errorCode, String errorMessage, @Nullable String sql) {
|
||||
SQLiteErrorCode code = SQLiteErrorCode.getErrorCode(errorCode);
|
||||
String msg;
|
||||
if (code == SQLiteErrorCode.UNKNOWN_ERROR) {
|
||||
msg = code + ":" + errorCode + " (" + errorMessage + ")";
|
||||
}
|
||||
else {
|
||||
msg = code + " (" + errorMessage + ")";
|
||||
}
|
||||
|
||||
if (sql != null) {
|
||||
msg += " (sql=" + sql + ")";
|
||||
}
|
||||
return new SQLiteException(msg, code);
|
||||
}
|
||||
|
||||
public interface ProgressObserver {
|
||||
void progress(int remaining, int pageCount);
|
||||
}
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 David Crawshaw <david@zentus.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.jetbrains.sqlite.core;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.sqlite.BusyHandler;
|
||||
import org.jetbrains.sqlite.Collation;
|
||||
import org.jetbrains.sqlite.Function;
|
||||
import org.jetbrains.sqlite.ProgressHandler;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/** This class provides a thin JNI layer over the SQLite3 C API. */
|
||||
public final class NativeDB extends DB {
|
||||
private static final int DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS = 100;
|
||||
private static final int DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL = 3;
|
||||
private static final int DEFAULT_PAGES_PER_BACKUP_STEP = 100;
|
||||
|
||||
/** SQLite connection handle. */
|
||||
private final long pointer = 0;
|
||||
/** busy handler pointer to JNI global busyhandler reference. */
|
||||
private final long busyHandler = 0;
|
||||
// pointer to commit listener structure, if enabled.
|
||||
private final long commitListener = 0;
|
||||
|
||||
// WRAPPER FUNCTIONS ////////////////////////////////////////////
|
||||
// pointer to update listener structure, if enabled.
|
||||
private final long updateListener = 0;
|
||||
/** handler pointer to JNI global progressHandler reference. */
|
||||
private long progressHandler;
|
||||
|
||||
public NativeDB() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** @see DB#_open(String, int) */
|
||||
@Override
|
||||
protected synchronized void _open(String file, int openFlags) throws SQLException {
|
||||
_open_utf8(stringToUtf8ByteArray(file), openFlags);
|
||||
}
|
||||
|
||||
synchronized native void _open_utf8(byte[] fileUtf8, int openFlags) throws SQLException;
|
||||
|
||||
/** @see DB#_close() */
|
||||
@Override
|
||||
protected synchronized native void _close() throws SQLException;
|
||||
|
||||
/** @see DB#_exec(String) */
|
||||
@Override
|
||||
public synchronized int _exec(String sql) throws SQLException {
|
||||
return _exec_utf8(stringToUtf8ByteArray(sql));
|
||||
}
|
||||
|
||||
synchronized native int _exec_utf8(byte[] sqlUtf8) throws SQLException;
|
||||
|
||||
/** @see DB#shared_cache(boolean) */
|
||||
@Override
|
||||
public synchronized native int shared_cache(boolean enable);
|
||||
|
||||
/** @see DB#enable_load_extension(boolean) */
|
||||
@Override
|
||||
public synchronized native int enable_load_extension(boolean enable);
|
||||
|
||||
/** @see DB#interrupt() */
|
||||
@Override
|
||||
public native void interrupt();
|
||||
|
||||
/** @see DB#busy_timeout(int) */
|
||||
@Override
|
||||
public synchronized native void busy_timeout(int ms);
|
||||
|
||||
/** @see DB#busy_handler(BusyHandler) */
|
||||
@Override
|
||||
public synchronized native void busy_handler(BusyHandler busyHandler);
|
||||
|
||||
/** @see DB#prepare(String) */
|
||||
@Override
|
||||
protected synchronized SafeStatementPointer prepare(@NotNull String sql) throws SQLException {
|
||||
return new SafeStatementPointer(this, prepare_utf8(stringToUtf8ByteArray(sql)));
|
||||
}
|
||||
|
||||
// byte[] instead of string is actually more performant
|
||||
public synchronized native long prepare_utf8(byte[] sqlUtf8) throws SQLException;
|
||||
|
||||
/** @see DB#errmsg() */
|
||||
@Override
|
||||
synchronized String errmsg() {
|
||||
return utf8ByteBufferToString(errmsg_utf8());
|
||||
}
|
||||
|
||||
synchronized native ByteBuffer errmsg_utf8();
|
||||
|
||||
/** @see DB#libversion() */
|
||||
@Override
|
||||
public synchronized String libversion() {
|
||||
return utf8ByteBufferToString(libversion_utf8());
|
||||
}
|
||||
|
||||
native ByteBuffer libversion_utf8();
|
||||
|
||||
/** @see DB#changes() */
|
||||
@Override
|
||||
public synchronized native long changes();
|
||||
|
||||
/** @see DB#total_changes() */
|
||||
@Override
|
||||
public synchronized native long total_changes();
|
||||
|
||||
/** @see DB#finalize(long) */
|
||||
@Override
|
||||
public synchronized native int finalize(long stmt);
|
||||
|
||||
/** @see DB#step(long) */
|
||||
@Override
|
||||
public synchronized native int step(long stmt);
|
||||
|
||||
@Override
|
||||
public synchronized native int reset(long stmt);
|
||||
|
||||
/** @see DB#clear_bindings(long) */
|
||||
@Override
|
||||
public synchronized native int clear_bindings(long stmt);
|
||||
|
||||
/** @see DB#bind_parameter_count(long) */
|
||||
@Override
|
||||
public synchronized native int bind_parameter_count(long stmt);
|
||||
|
||||
/** @see DB#column_count(long) */
|
||||
@Override
|
||||
public synchronized native int column_count(long stmt);
|
||||
|
||||
/** @see DB#column_type(long, int) */
|
||||
@Override
|
||||
public synchronized native int column_type(long stmt, int col);
|
||||
|
||||
/** @see DB#column_decltype(long, int) */
|
||||
@Override
|
||||
public synchronized String column_decltype(long stmt, int col) {
|
||||
return utf8ByteBufferToString(column_decltype_utf8(stmt, col));
|
||||
}
|
||||
|
||||
synchronized native ByteBuffer column_decltype_utf8(long stmt, int col);
|
||||
|
||||
/** @see DB#column_table_name(long, int) */
|
||||
@Override
|
||||
public synchronized String column_table_name(long stmt, int col) {
|
||||
return utf8ByteBufferToString(column_table_name_utf8(stmt, col));
|
||||
}
|
||||
|
||||
synchronized native ByteBuffer column_table_name_utf8(long stmt, int col);
|
||||
|
||||
/** @see DB#column_name(long, int) */
|
||||
@Override
|
||||
public synchronized String column_name(long stmt, int col) {
|
||||
return utf8ByteBufferToString(column_name_utf8(stmt, col));
|
||||
}
|
||||
|
||||
synchronized native ByteBuffer column_name_utf8(long stmt, int col);
|
||||
|
||||
/** @see DB#column_text(long, int) */
|
||||
@Override
|
||||
public synchronized String column_text(long statementPointer, int zeroBasedColumnIndex) {
|
||||
return utf8ByteBufferToString(column_text_utf8(statementPointer, zeroBasedColumnIndex));
|
||||
}
|
||||
|
||||
synchronized native ByteBuffer column_text_utf8(long stmt, int col);
|
||||
|
||||
/** @see DB#column_blob(long, int) */
|
||||
@Override
|
||||
public synchronized native byte[] column_blob(long statementPointer, int zeroBasedColumnIndex);
|
||||
|
||||
/** @see DB#column_double(long, int) */
|
||||
@Override
|
||||
public synchronized native double column_double(long statementPointer, int zeroBasedColumnIndex);
|
||||
|
||||
/** @see DB#column_long(long, int) */
|
||||
@Override
|
||||
public synchronized native long column_long(long statementPointer, int zeroBasedColumnIndex);
|
||||
|
||||
/** @see DB#column_int(long, int) */
|
||||
@Override
|
||||
public synchronized native int column_int(long statementPointer, int zeroBasedColumnIndex);
|
||||
|
||||
/** @see DB#bind_null(long, int) */
|
||||
@Override
|
||||
synchronized native int bind_null(long stmt, int oneBasedColumnIndex);
|
||||
|
||||
/** @see DB#bind_int(long, int, int) */
|
||||
@Override
|
||||
public synchronized native int bind_int(long stmt, int oneBasedColumnIndex, int v);
|
||||
|
||||
/** @see DB#bind_long(long, int, long) */
|
||||
@Override
|
||||
public synchronized native int bind_long(long stmt, int oneBasedColumnIndex, long v);
|
||||
|
||||
/** @see DB#bind_double(long, int, double) */
|
||||
@Override
|
||||
synchronized native int bind_double(long stmt, int oneBasedColumnIndex, double v);
|
||||
|
||||
/** @see DB#bind_text(long, int, String) */
|
||||
@Override
|
||||
synchronized int bind_text(long stmt, int oneBasedColumnIndex, String v) {
|
||||
return bind_text_utf8(stmt, oneBasedColumnIndex, stringToUtf8ByteArray(v));
|
||||
}
|
||||
|
||||
synchronized native int bind_text_utf8(long stmt, int pos, byte[] vUtf8);
|
||||
|
||||
/** @see DB#bind_blob(long, int, byte[]) */
|
||||
@Override
|
||||
synchronized native int bind_blob(long stmt, int oneBasedColumnIndex, byte[] v);
|
||||
|
||||
/** @see DB#result_null(long) */
|
||||
@Override
|
||||
public synchronized native void result_null(long context);
|
||||
|
||||
/** @see DB#result_text(long, String) */
|
||||
@Override
|
||||
public synchronized void result_text(long context, String val) {
|
||||
result_text_utf8(context, stringToUtf8ByteArray(val));
|
||||
}
|
||||
|
||||
synchronized native void result_text_utf8(long context, byte[] valUtf8);
|
||||
|
||||
/** @see DB#result_blob(long, byte[]) */
|
||||
@Override
|
||||
public synchronized native void result_blob(long context, byte[] val);
|
||||
|
||||
/** @see DB#result_double(long, double) */
|
||||
@Override
|
||||
public synchronized native void result_double(long context, double val);
|
||||
|
||||
/** @see DB#result_long(long, long) */
|
||||
@Override
|
||||
public synchronized native void result_long(long context, long val);
|
||||
|
||||
/** @see DB#result_int(long, int) */
|
||||
@Override
|
||||
public synchronized native void result_int(long context, int val);
|
||||
|
||||
/** @see DB#result_error(long, String) */
|
||||
@Override
|
||||
public synchronized void result_error(long context, String err) {
|
||||
result_error_utf8(context, stringToUtf8ByteArray(err));
|
||||
}
|
||||
|
||||
synchronized native void result_error_utf8(long context, byte[] errUtf8);
|
||||
|
||||
/** @see DB#value_text(Function, int) */
|
||||
@Override
|
||||
public synchronized String value_text(Function f, int arg) {
|
||||
return utf8ByteBufferToString(value_text_utf8(f, arg));
|
||||
}
|
||||
|
||||
synchronized native ByteBuffer value_text_utf8(Function f, int argUtf8);
|
||||
|
||||
/** @see DB#value_blob(Function, int) */
|
||||
@Override
|
||||
public synchronized native byte[] value_blob(Function f, int arg);
|
||||
|
||||
/** @see DB#value_double(Function, int) */
|
||||
@Override
|
||||
public synchronized native double value_double(Function f, int arg);
|
||||
|
||||
/** @see DB#value_long(Function, int) */
|
||||
@Override
|
||||
public synchronized native long value_long(Function f, int arg);
|
||||
|
||||
/** @see DB#value_int(Function, int) */
|
||||
@Override
|
||||
public synchronized native int value_int(Function f, int arg);
|
||||
|
||||
/** @see DB#value_type(Function, int) */
|
||||
@Override
|
||||
public synchronized native int value_type(Function f, int arg);
|
||||
|
||||
/** @see DB#create_function(String, Function, int, int) */
|
||||
@Override
|
||||
public synchronized int create_function(String name, Function func, int nArgs, int flags)
|
||||
throws SQLException {
|
||||
return create_function_utf8(nameToUtf8ByteArray("function", name), func, nArgs, flags);
|
||||
}
|
||||
|
||||
synchronized native int create_function_utf8(
|
||||
byte[] nameUtf8, Function func, int nArgs, int flags);
|
||||
|
||||
/** @see DB#destroy_function(String) */
|
||||
@Override
|
||||
public synchronized int destroy_function(String name) throws SQLException {
|
||||
return destroy_function_utf8(nameToUtf8ByteArray("function", name));
|
||||
}
|
||||
|
||||
synchronized native int destroy_function_utf8(byte[] nameUtf8);
|
||||
|
||||
/** @see DB#create_collation(String, Collation) */
|
||||
@Override
|
||||
public synchronized int create_collation(String name, Collation coll) throws SQLException {
|
||||
return create_collation_utf8(nameToUtf8ByteArray("collation", name), coll);
|
||||
}
|
||||
|
||||
synchronized native int create_collation_utf8(byte[] nameUtf8, Collation coll);
|
||||
|
||||
/** @see DB#destroy_collation(String) */
|
||||
@Override
|
||||
public synchronized int destroy_collation(String name) throws SQLException {
|
||||
return destroy_collation_utf8(nameToUtf8ByteArray("collation", name));
|
||||
}
|
||||
|
||||
synchronized native int destroy_collation_utf8(byte[] nameUtf8);
|
||||
|
||||
@Override
|
||||
public synchronized native int limit(int id, int value) throws SQLException;
|
||||
|
||||
private static byte[] nameToUtf8ByteArray(String nameType, String name) throws SQLException {
|
||||
final byte[] nameUtf8 = stringToUtf8ByteArray(name);
|
||||
if (name == null || name.isEmpty() || nameUtf8.length > 255) {
|
||||
throw new SQLException("invalid " + nameType + " name: '" + name + "'");
|
||||
}
|
||||
return nameUtf8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DB#backup(String, String,
|
||||
* ProgressObserver)
|
||||
*/
|
||||
@Override
|
||||
public int backup(String dbName, String destFileName, ProgressObserver observer)
|
||||
throws SQLException {
|
||||
return backup(
|
||||
stringToUtf8ByteArray(dbName),
|
||||
stringToUtf8ByteArray(destFileName),
|
||||
observer,
|
||||
DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS,
|
||||
DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL,
|
||||
DEFAULT_PAGES_PER_BACKUP_STEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DB#backup(String, String, ProgressObserver, int, int,
|
||||
* int)
|
||||
*/
|
||||
@Override
|
||||
public int backup(
|
||||
String dbName,
|
||||
String destFileName,
|
||||
ProgressObserver observer,
|
||||
int sleepTimeMillis,
|
||||
int nTimeouts,
|
||||
int pagesPerStep)
|
||||
throws SQLException {
|
||||
return backup(
|
||||
stringToUtf8ByteArray(dbName),
|
||||
stringToUtf8ByteArray(destFileName),
|
||||
observer,
|
||||
sleepTimeMillis,
|
||||
nTimeouts,
|
||||
pagesPerStep);
|
||||
}
|
||||
|
||||
synchronized native int backup(
|
||||
byte[] dbNameUtf8,
|
||||
byte[] destFileNameUtf8,
|
||||
ProgressObserver observer,
|
||||
int sleepTimeMillis,
|
||||
int nTimeouts,
|
||||
int pagesPerStep)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* @see DB#restore(String, String,
|
||||
* ProgressObserver)
|
||||
*/
|
||||
@Override
|
||||
public synchronized int restore(String dbName, String sourceFileName, ProgressObserver observer)
|
||||
throws SQLException {
|
||||
|
||||
return restore(
|
||||
dbName,
|
||||
sourceFileName,
|
||||
observer,
|
||||
DEFAULT_BACKUP_BUSY_SLEEP_TIME_MILLIS,
|
||||
DEFAULT_BACKUP_NUM_BUSY_BEFORE_FAIL,
|
||||
DEFAULT_PAGES_PER_BACKUP_STEP);
|
||||
}
|
||||
|
||||
// COMPOUND FUNCTIONS (for optimisation) /////////////////////////
|
||||
|
||||
/** @see DB#restore(String, String, ProgressObserver, int, int, int) */
|
||||
@Override
|
||||
public synchronized int restore(
|
||||
String dbName,
|
||||
String sourceFileName,
|
||||
ProgressObserver observer,
|
||||
int sleepTimeMillis,
|
||||
int nTimeouts,
|
||||
int pagesPerStep)
|
||||
throws SQLException {
|
||||
|
||||
return restore(
|
||||
stringToUtf8ByteArray(dbName),
|
||||
stringToUtf8ByteArray(sourceFileName),
|
||||
observer,
|
||||
sleepTimeMillis,
|
||||
nTimeouts,
|
||||
pagesPerStep);
|
||||
}
|
||||
|
||||
synchronized native int restore(
|
||||
byte[] dbNameUtf8,
|
||||
byte[] sourceFileName,
|
||||
ProgressObserver observer,
|
||||
int sleepTimeMillis,
|
||||
int nTimeouts,
|
||||
int pagesPerStep)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Provides metadata for table columns.
|
||||
*
|
||||
* @return For each column returns: <br>
|
||||
* res[col][0] = true if column constrained NOT NULL<br>
|
||||
* res[col][1] = true if column is part of the primary key<br>
|
||||
* res[col][2] = true if column is auto-increment.
|
||||
* @see DB#column_metadata(long)
|
||||
*/
|
||||
@Override
|
||||
public synchronized native boolean[][] column_metadata(long stmt);
|
||||
|
||||
@Override
|
||||
synchronized native void set_commit_listener(boolean enabled);
|
||||
|
||||
@Override
|
||||
synchronized native void set_update_listener(boolean enabled);
|
||||
|
||||
@Override
|
||||
public synchronized native void register_progress_handler(
|
||||
int vmCalls, ProgressHandler progressHandler) throws SQLException;
|
||||
|
||||
@Override
|
||||
public synchronized native void clear_progress_handler() throws SQLException;
|
||||
|
||||
/**
|
||||
* Getter for native pointer to validate memory is properly cleaned up in unit tests
|
||||
*
|
||||
* @return a native pointer to validate memory is properly cleaned up in unit tests
|
||||
*/
|
||||
long getBusyHandler() {
|
||||
return busyHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for native pointer to validate memory is properly cleaned up in unit tests
|
||||
*
|
||||
* @return a native pointer to validate memory is properly cleaned up in unit tests
|
||||
*/
|
||||
long getCommitListener() {
|
||||
return commitListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for native pointer to validate memory is properly cleaned up in unit tests
|
||||
*
|
||||
* @return a native pointer to validate memory is properly cleaned up in unit tests
|
||||
*/
|
||||
long getUpdateListener() {
|
||||
return updateListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for native pointer to validate memory is properly cleaned up in unit tests
|
||||
*
|
||||
* @return a native pointer to validate memory is properly cleaned up in unit tests
|
||||
*/
|
||||
long getProgressHandler() {
|
||||
return progressHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an SQLException. Called from native code
|
||||
*
|
||||
* @param msg Message for the SQLException.
|
||||
* @throws SQLException the generated SQLException
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
static void throwex(String msg) throws SQLException {
|
||||
throw new SQLException(msg);
|
||||
}
|
||||
|
||||
static byte[] stringToUtf8ByteArray(String str) {
|
||||
return str.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
static String utf8ByteBufferToString(ByteBuffer buffer) {
|
||||
if (buffer == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] buff = new byte[buffer.remaining()];
|
||||
buffer.get(buff);
|
||||
return new String(buff, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import com.intellij.openapi.util.io.NioFiles
|
||||
import com.intellij.util.ResourceUtil
|
||||
import com.intellij.util.io.DigestUtil
|
||||
import com.intellij.util.system.CpuArch
|
||||
import org.jetbrains.sqlite.core.Codes
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardCopyOption
|
||||
@@ -15,7 +14,7 @@ import java.nio.file.StandardCopyOption
|
||||
private var extracted = false
|
||||
|
||||
// The version of the SQLite JDBC driver.
|
||||
private const val VERSION: String = "3.40.0.0"
|
||||
private const val VERSION: String = "3.40.0.1-2"
|
||||
|
||||
/**
|
||||
* Loads the SQLite interface backend.
|
||||
@@ -32,20 +31,11 @@ internal fun loadNativeDb() {
|
||||
extracted = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads SQLite native library using given a path and name of the library.
|
||||
*/
|
||||
private fun loadSqliteNativeLibrary() {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
var nativeLibraryName = System.mapLibraryName("sqlitejdbc")?.replace(".dylib", ".jnilib")!!
|
||||
val relativeDirName = "${osNameToDirName()}/${if (CpuArch.isArm64()) "aarch64" else "x86_64"}"
|
||||
val libPath = try {
|
||||
PathManager.getLibPath()
|
||||
}
|
||||
catch (ignore: RuntimeException) {
|
||||
// unit test or benchmark - no home path
|
||||
null
|
||||
}
|
||||
val nativeLibraryName = System.mapLibraryName("sqliteij")?.replace(".dylib", ".jnilib")!!
|
||||
val relativeDirName = "${osNameToDirName()}-${if (CpuArch.isArm64()) "aarch64" else "x86_64"}"
|
||||
val libPath = getLibPath()
|
||||
if (libPath != null) {
|
||||
val nativeLibFile = Path.of(libPath, "native", relativeDirName, nativeLibraryName).toAbsolutePath().normalize()
|
||||
if (Files.exists(nativeLibFile)) {
|
||||
@@ -55,19 +45,9 @@ private fun loadSqliteNativeLibrary() {
|
||||
}
|
||||
|
||||
// load the os-dependent library from the jar file
|
||||
val nativeLibraryPath = "sqlite-native/$relativeDirName"
|
||||
val classLoader = Codes::class.java.classLoader
|
||||
var hasNativeLib = classLoader.getResource("$nativeLibraryPath/$nativeLibraryName") != null
|
||||
if (!hasNativeLib && SystemInfoRt.isMac) {
|
||||
// fix for openjdk7 for Mac
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val altName = "libsqlitejdbc.jnilib"
|
||||
if (classLoader.getResource("$nativeLibraryPath/$altName") != null) {
|
||||
nativeLibraryName = altName
|
||||
hasNativeLib = true
|
||||
}
|
||||
}
|
||||
|
||||
val nativeLibraryPath = "sqlite/$relativeDirName"
|
||||
val classLoader = SqliteCodes::class.java.classLoader
|
||||
val hasNativeLib = classLoader.getResource("$nativeLibraryPath/$nativeLibraryName") != null
|
||||
if (hasNativeLib) {
|
||||
// try extracting the library from jar
|
||||
val tempDir = if (libPath == null) {
|
||||
@@ -85,12 +65,27 @@ private fun loadSqliteNativeLibrary() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLibPath(): String? {
|
||||
if (System.getProperty("sqlite.use.path.manager") == "false") {
|
||||
return null
|
||||
}
|
||||
|
||||
val libPath = try {
|
||||
PathManager.getLibPath()
|
||||
}
|
||||
catch (ignore: RuntimeException) {
|
||||
// unit test or benchmark - no home path
|
||||
null
|
||||
}
|
||||
return libPath
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts and loads the specified library file to the target folder
|
||||
*/
|
||||
private fun extractAndLoadLibraryFile(libFolderForCurrentOS: String, libraryFileName: String, tempDir: Path) {
|
||||
val nativeLibraryFilePath = "$libFolderForCurrentOS/$libraryFileName"
|
||||
val classLoader = Codes::class.java.classLoader
|
||||
val classLoader = SqliteCodes::class.java.classLoader
|
||||
|
||||
val expectedHash = ResourceUtil.getResourceAsBytes("$nativeLibraryFilePath.sha256", classLoader)!!.decodeToString()
|
||||
|
||||
|
||||
13
platform/sqlite/test/org/jetbrains/sqlite/SqlTestMain.kt
Normal file
13
platform/sqlite/test/org/jetbrains/sqlite/SqlTestMain.kt
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
object SqlTestMain {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
System.setProperty("sqlite.use.path.manager", "false")
|
||||
SqliteConnection(file = null).use {
|
||||
testInsert(SqliteConnection(file = null))
|
||||
println("succeed")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
package org.jetbrains.sqlite
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.sqlite.core.SqliteConnection
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -24,32 +23,7 @@ class SqliteTest {
|
||||
|
||||
@Test
|
||||
fun insert() {
|
||||
connection.execute("""
|
||||
create table log (
|
||||
commitId integer primary key,
|
||||
message text not null,
|
||||
authorTime integer not null,
|
||||
commitTime integer not null,
|
||||
committerId integer null
|
||||
) strict
|
||||
""")
|
||||
|
||||
connection.prepareStatement("""
|
||||
insert into log(commitId, message, authorTime, commitTime, committerId)
|
||||
values(?, ?, ?, ?, ?)
|
||||
on conflict(commitId) do update set message=excluded.message
|
||||
""", ObjectBinder(5)).use { statement ->
|
||||
statement.binder.bind(12, "test", 2, 2, 1)
|
||||
statement.binder.addBatch()
|
||||
statement.executeBatch()
|
||||
}
|
||||
|
||||
connection.prepareStatement("select message from log where commitId = ?", IntBinder(paramCount = 1)).use { statement ->
|
||||
statement.binder.bind(12)
|
||||
val resultSet = statement.executeQuery()
|
||||
assertThat(resultSet.next()).isTrue()
|
||||
assertThat(resultSet.getString(0)).isEqualTo("test")
|
||||
}
|
||||
testInsert(connection)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,4 +100,33 @@ class SqliteTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun testInsert(connection: SqliteConnection) {
|
||||
connection.execute("""
|
||||
create table log (
|
||||
commitId integer primary key,
|
||||
message text not null,
|
||||
authorTime integer not null,
|
||||
commitTime integer not null,
|
||||
committerId integer null
|
||||
) strict
|
||||
""")
|
||||
|
||||
connection.prepareStatement("""
|
||||
insert into log(commitId, message, authorTime, commitTime, committerId)
|
||||
values(?, ?, ?, ?, ?)
|
||||
on conflict(commitId) do update set message=excluded.message
|
||||
""", ObjectBinder(5)).use { statement ->
|
||||
statement.binder.bind(12, "test", 2, 2, 1)
|
||||
statement.binder.addBatch()
|
||||
statement.executeBatch()
|
||||
}
|
||||
|
||||
connection.prepareStatement("select message from log where commitId = ?", IntBinder(paramCount = 1)).use { statement ->
|
||||
statement.binder.bind(12)
|
||||
val resultSet = statement.executeQuery()
|
||||
assertThat(resultSet.next()).isTrue()
|
||||
assertThat(resultSet.getString(0)).isEqualTo("test")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,7 @@ import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import it.unimi.dsi.fastutil.ints.IntSet
|
||||
import kotlinx.coroutines.*
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.sqlite.EmptyBinder
|
||||
import org.jetbrains.sqlite.IntBinder
|
||||
import org.jetbrains.sqlite.ObjectBinder
|
||||
import org.jetbrains.sqlite.StatementCollection
|
||||
import org.jetbrains.sqlite.core.SqliteConnection
|
||||
import org.jetbrains.sqlite.core.SqlitePreparedStatement
|
||||
import org.jetbrains.sqlite.*
|
||||
import java.nio.file.Files
|
||||
import java.util.*
|
||||
import java.util.function.IntConsumer
|
||||
|
||||
Reference in New Issue
Block a user