[Git][java-team/xerial-sqlite-jdbc][upstream] New upstream version 3.46.1.3+dfsg
Pierre Gruet (@pgt)
gitlab at salsa.debian.org
Wed Oct 9 08:29:06 BST 2024
Pierre Gruet pushed to branch upstream at Debian Java Maintainers / xerial-sqlite-jdbc
Commits:
a19678a2 by Pierre Gruet at 2024-10-08T22:57:40+02:00
New upstream version 3.46.1.3+dfsg
- - - - -
29 changed files:
- Makefile
- Makefile.common
- README.adoc
- USAGE.md
- VERSION
- demo/Sample.java
- + docker/dockcross-riscv64
- pom.xml
- src/main/java/org/sqlite/JDBC.java
- src/main/java/org/sqlite/SQLiteConfig.java
- src/main/java/org/sqlite/SQLiteConnectionConfig.java
- src/main/java/org/sqlite/SQLiteDataSource.java
- src/main/java/org/sqlite/SQLiteJDBCLoader.java
- src/main/java/org/sqlite/core/CoreStatement.java
- src/main/java/org/sqlite/core/NativeDB.java
- src/main/java/org/sqlite/jdbc3/JDBC3DatabaseMetaData.java
- src/main/java/org/sqlite/jdbc3/JDBC3Statement.java
- + src/main/java/org/sqlite/util/Logger.java
- + src/main/java/org/sqlite/util/LoggerFactory.java
- src/main/java/org/sqlite/util/OSInfo.java
- src/main/java9/org/sqlite/nativeimage/SqliteJdbcFeature.java
- src/test/java/org/sqlite/DBMetaDataTest.java
- src/test/java/org/sqlite/MultipleClassLoaderTest.java
- src/test/java/org/sqlite/PrepStmtTest.java
- src/test/java/org/sqlite/SQLiteConfigTest.java
- src/test/java/org/sqlite/SQLiteDataSourceTest.java
- src/test/java/org/sqlite/StatementTest.java
- src/test/java/org/sqlite/architecture/CodingRulesTest.java
- src/test/java/org/sqlite/util/OSInfoTest.java
Changes:
=====================================
Makefile
=====================================
@@ -121,7 +121,7 @@ NATIVE_TARGET_DIR:=$(TARGET)/classes/org/sqlite/native/$(OS_NAME)/$(OS_ARCH)
NATIVE_DLL:=$(NATIVE_DIR)/$(LIBNAME)
# For cross-compilation, install docker. See also https://github.com/dockcross/dockcross
-native-all: native win32 win64 win-armv7 win-arm64 mac64-signed mac-arm64-signed linux32 linux64 freebsd32 freebsd64 freebsd-arm64 linux-arm linux-armv6 linux-armv7 linux-arm64 linux-android-arm linux-android-arm64 linux-android-x86 linux-android-x64 linux-ppc64 linux-musl32 linux-musl64 linux-musl-arm64
+native-all: native win32 win64 win-armv7 win-arm64 mac64-signed mac-arm64-signed linux32 linux64 freebsd32 freebsd64 freebsd-arm64 linux-arm linux-armv6 linux-armv7 linux-arm64 linux-android-arm linux-android-arm64 linux-android-x86 linux-android-x64 linux-ppc64 linux-musl32 linux-musl64 linux-musl-arm64 linux-riscv64
native: $(NATIVE_DLL)
@@ -194,6 +194,9 @@ linux-android-x64: $(SQLITE_UNPACKED) jni-header
linux-ppc64: $(SQLITE_UNPACKED) jni-header
./docker/dockcross-ppc64 -a $(DOCKER_RUN_OPTS) bash -c 'make clean-native native CROSS_PREFIX=powerpc64le-unknown-linux-gnu- OS_NAME=Linux OS_ARCH=ppc64'
+linux-riscv64: $(SQLITE_UNPACKED) jni-header
+ ./docker/dockcross-riscv64 -a $(DOCKER_RUN_OPTS) bash -c 'make clean-native native CROSS_PREFIX=riscv64-unknown-linux-gnu- OS_NAME=Linux OS_ARCH=riscv64'
+
mac64: $(SQLITE_UNPACKED) jni-header
docker run $(DOCKER_RUN_OPTS) -v $$PWD:/workdir -e CROSS_TRIPLE=x86_64-apple-darwin multiarch/crossbuild make clean-native native OS_NAME=Mac OS_ARCH=x86_64
=====================================
Makefile.common
=====================================
@@ -52,7 +52,7 @@ endif
# os=Default is meant to be generic unix/linux
-known_targets := Linux-x86 Linux-x86_64 Linux-arm Linux-armv6 Linux-armv7 Linux-Android-arm Linux-Android-aarch64 Linux-Android-x86 Linux-Android-x86_64 Linux-ppc64 Mac-x86 Mac-x86_64 Mac-aarch64 DragonFly-x86_64 FreeBSD-x86 FreeBSD-x86_64 FreeBSD-aarch64 OpenBSD-x86_64 Windows-x86 Windows-x86_64 Windows-armv7 Windows-aarch64 SunOS-sparcv9 HPUX-ia64_32
+known_targets := Linux-x86 Linux-x86_64 Linux-arm Linux-armv6 Linux-armv7 Linux-Android-arm Linux-Android-aarch64 Linux-Android-x86 Linux-Android-x86_64 Linux-ppc64 Linux-riscv64 Mac-x86 Mac-x86_64 Mac-aarch64 DragonFly-x86_64 FreeBSD-x86 FreeBSD-x86_64 FreeBSD-aarch64 OpenBSD-x86_64 Windows-x86 Windows-x86_64 Windows-armv7 Windows-aarch64 SunOS-sparcv9 HPUX-ia64_32
target := $(OS_NAME)-$(OS_ARCH)
ifeq (,$(findstring $(strip $(target)),$(known_targets)))
@@ -141,6 +141,13 @@ Linux-ppc64_LINKFLAGS := $(Default_LINKFLAGS)
Linux-ppc64_LIBNAME := libsqlitejdbc.so
Linux-ppc64_SQLITE_FLAGS :=
+Linux-riscv64_CC := $(CROSS_PREFIX)gcc
+Linux-riscv64_STRIP := $(CROSS_PREFIX)strip
+Linux-riscv64_CCFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_linux -Os -fPIC -fvisibility=hidden
+Linux-riscv64_LINKFLAGS := $(Default_LINKFLAGS)
+Linux-riscv64_LIBNAME := libsqlitejdbc.so
+Linux-riscv64_SQLITE_FLAGS :=
+
DragonFly-x86_64_CC := $(CROSS_PREFIX)cc
DragonFly-x86_64_STRIP := $(CROSS_PREFIX)strip
DragonFly-x86_64_CCFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_linux -O2 -fPIC -fvisibility=hidden
=====================================
README.adoc
=====================================
@@ -1,5 +1,5 @@
= SQLite JDBC Driver
-:project-version: 3.45.2.0
+:project-version: 3.46.1.3
image:https://img.shields.io/github/actions/workflow/status/xerial/sqlite-jdbc/ci.yml?branch=master[GitHub Workflow Status (branch),link=https://github.com/xerial/sqlite-jdbc/actions/workflows/ci.yml?query=branch%3Amaster]
image:https://badges.gitter.im/xerial/sqlite-jdbc.svg[Join the chat,link=https://gitter.im/xerial/sqlite-jdbc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge]
@@ -29,19 +29,18 @@ SQLite JDBC is a library for accessing SQLite databases through the JDBC API. Fo
. <<Download,Download>> `sqlite-jdbc-{project-version}.jar`
then append this jar file into your classpath.
-. https://search.maven.org/remotecontent?filepath=org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar[Download] `slf4j-api-1.7.36.jar` then append this jar file into your classpath.
. Open a SQLite database connection from your code. (see the example below)
=== Example usage
-Assuming `sqlite-jdbc-{project-version}.jar` and `slf4j-api-1.7.36.jar` are placed in the current directory.
+Assuming `sqlite-jdbc-{project-version}.jar` is placed in the current directory.
[source,shell,subs="attributes+"]
----
> javac Sample.java
-> java -classpath ".;sqlite-jdbc-{project-version}.jar;slf4j-api-1.7.36.jar" Sample # in Windows
+> java -classpath ".;sqlite-jdbc-{project-version}.jar" Sample # in Windows
or
-> java -classpath ".:sqlite-jdbc-{project-version}.jar:slf4j-api-1.7.36.jar" Sample # in macOS or Linux
+> java -classpath ".:sqlite-jdbc-{project-version}.jar" Sample # in macOS or Linux
name = leo
id = 1
name = yui
@@ -62,7 +61,7 @@ id = 2
{
public static void main(String[] args)
{
- // NOTE: Connection and Statement are AutoClosable.
+ // NOTE: Connection and Statement are AutoCloseable.
// Don't forget to close them both in order to avoid leaks.
try
(
@@ -110,14 +109,14 @@ Since sqlite-jdbc-3.6.19, the natively compiled SQLite engines will be used for
the following operating systems:
|===
-| |x86 |x86_64 |armv5 |armv6 |armv7 |arm64 |ppc64
-
-|Windows |✔ |✔ | | |✔ |✔ |
-|macOS | |✔ | | | |✔ |
-|Linux (libc) |✔ |✔ |✔ |✔ |✔ |✔ |✔
-|Linux (musl) |✔ |✔ | | | |✔ |
-|Android |✔ |✔ |✔ | | |✔ |
-|FreeBSD |✔ |✔ | | | |✔ |
+| |x86 |x86_64 |armv5 |armv6 |armv7 |arm64 |ppc64 | riscv64
+
+|Windows |✔ |✔ | | |✔ |✔ | |
+|macOS | |✔ | | | |✔ | |
+|Linux (libc) |✔ |✔ |✔ |✔ |✔ |✔ |✔ |✔
+|Linux (musl) |✔ |✔ | | | |✔ | |
+|Android |✔ |✔ |✔ | | |✔ | |
+|FreeBSD |✔ |✔ | | | |✔ | |
|===
In the other OSs not listed above, the pure-java SQLite is used. (Applies to versions before 3.7.15)
=====================================
USAGE.md
=====================================
@@ -11,14 +11,14 @@ Opening a UNIX (Linux, maxOS, etc.) file `/home/leo/work/mydatabase.db`
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:/home/leo/work/mydatabase.db")) { /*...*/ }
```
-## How to Use Memory Databases
-SQLite supports on-memory database management, which does not create any database files. To use a memory database in your Java code, get the database connection as follows:
+## How to Use Memory or Temporary Databases
+SQLite supports in-memory databases, which do not create any database files. To use a memory database in your Java code, get the database connection as follows:
```java
try (Connection connection = DriverManager.getConnection("jdbc:sqlite::memory:")) { /*...*/ }
```
-And also, you can create memory database as follows:
+You can create temporary database as follows:
```java
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:")) { /*...*/ }
```
@@ -139,6 +139,22 @@ You set the mode at the connection string level:
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:db.sqlite?hexkey_mode=sse", "", "AE...")) { /*...*/ }
```
+## Generated keys
+
+SQLite has limited support to retrieve generated keys, using [last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html), with the following limitations:
+- a single ID can be retrieved, even if multiple rows were added or updated
+- it needs to be called right after the statement
+
+By default the driver will eagerly retrieve the generated keys after each statement, which may impact performances.
+
+You can disable the retrieval of generated keys in 3 ways:
+- via `SQLiteDataSource#setGetGeneratedKeys(false)`
+- via `SQLiteConnectionConfig#setGetGeneratedKeys(false)`:
+- using the pragma `jdbc.get_generated_keys`:
+```java
+try (Connection connection = DriverManager.getConnection("jdbc:sqlite::memory:?jdbc.get_generated_keys=false")) { /*...*/ }
+```
+
## Explicit read only transactions (use with Hibernate)
In order for the driver to be compliant with Hibernate, it needs to allow setting the read only flag after a connection has been created.
=====================================
VERSION
=====================================
@@ -1 +1 @@
-version=3.45.2
+version=3.46.1
=====================================
demo/Sample.java
=====================================
@@ -8,7 +8,7 @@
{
public static void main(String[] args)
{
- // NOTE: Connection and Statement are AutoClosable.
+ // NOTE: Connection and Statement are AutoCloseable.
// Don't forget to close them both in order to avoid leaks.
try
(
=====================================
docker/dockcross-riscv64
=====================================
@@ -0,0 +1,278 @@
+#!/usr/bin/env bash
+
+DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-riscv64:latest
+
+#------------------------------------------------------------------------------
+# Helpers
+#
+err() {
+ echo -e >&2 "ERROR: $*\n"
+}
+
+die() {
+ err "$*"
+ exit 1
+}
+
+has() {
+ # eg. has command update
+ local kind=$1
+ local name=$2
+
+ type -t $kind:$name | grep -q function
+}
+
+# If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative")
+if [ -z "$OCI_EXE" ]; then
+ if which podman >/dev/null 2>/dev/null; then
+ OCI_EXE=podman
+ elif which docker >/dev/null 2>/dev/null; then
+ OCI_EXE=docker
+ else
+ die "Cannot find a container executor. Search for docker and podman."
+ fi
+fi
+
+#------------------------------------------------------------------------------
+# Command handlers
+#
+command:update-image() {
+ $OCI_EXE pull $FINAL_IMAGE
+}
+
+help:update-image() {
+ echo "Pull the latest $FINAL_IMAGE ."
+}
+
+command:update-script() {
+ if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then
+ echo "$0 is up to date"
+ else
+ echo -n "Updating $0 ... "
+ $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok
+ fi
+}
+
+help:update-script() {
+ echo "Update $0 from $FINAL_IMAGE ."
+}
+
+command:update() {
+ command:update-image
+ command:update-script
+}
+
+help:update() {
+ echo "Pull the latest $FINAL_IMAGE, and then update $0 from that."
+}
+
+command:help() {
+ if [[ $# != 0 ]]; then
+ if ! has command $1; then
+ err \"$1\" is not an dockcross command
+ command:help
+ elif ! has help $1; then
+ err No help found for \"$1\"
+ else
+ help:$1
+ fi
+ else
+ cat >&2 <<ENDHELP
+Usage: dockcross [options] [--] command [args]
+
+By default, run the given *command* in an dockcross Docker container.
+
+The *options* can be one of:
+
+ --args|-a Extra args to the *docker run* command
+ --image|-i Docker cross-compiler image to use
+ --config|-c Bash script to source before running this script
+
+
+Additionally, there are special update commands:
+
+ update-image
+ update-script
+ update
+
+For update command help use: $0 help <command>
+ENDHELP
+ exit 1
+ fi
+}
+
+#------------------------------------------------------------------------------
+# Option processing
+#
+special_update_command=''
+while [[ $# != 0 ]]; do
+ case $1 in
+
+ --)
+ shift
+ break
+ ;;
+
+ --args|-a)
+ ARG_ARGS="$2"
+ shift 2
+ ;;
+
+ --config|-c)
+ ARG_CONFIG="$2"
+ shift 2
+ ;;
+
+ --image|-i)
+ ARG_IMAGE="$2"
+ shift 2
+ ;;
+ update|update-image|update-script)
+ special_update_command=$1
+ break
+ ;;
+ -*)
+ err Unknown option \"$1\"
+ command:help
+ exit
+ ;;
+
+ *)
+ break
+ ;;
+
+ esac
+done
+
+# The precedence for options is:
+# 1. command-line arguments
+# 2. environment variables
+# 3. defaults
+
+# Source the config file if it exists
+DEFAULT_DOCKCROSS_CONFIG=~/.dockcross
+FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}}
+
+[[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG"
+
+# Set the docker image
+FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}}
+
+# Handle special update command
+if [ "$special_update_command" != "" ]; then
+ case $special_update_command in
+
+ update)
+ command:update
+ exit $?
+ ;;
+
+ update-image)
+ command:update-image
+ exit $?
+ ;;
+
+ update-script)
+ command:update-script
+ exit $?
+ ;;
+
+ esac
+fi
+
+# Set the docker run extra args (if any)
+FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}}
+
+# Bash on Ubuntu on Windows
+UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "")
+# MSYS, Git Bash, etc.
+MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "")
+# CYGWIN
+CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "")
+
+if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then
+ USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )")
+fi
+
+# Change the PWD when working in Docker on Windows
+if [ -n "$UBUNTU_ON_WINDOWS" ]; then
+ WSL_ROOT="/mnt/"
+ CFG_FILE=/etc/wsl.conf
+ if [ -f "$CFG_FILE" ]; then
+ CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g')
+ eval "$CFG_CONTENT"
+ if [ -n "$root" ]; then
+ WSL_ROOT=$root
+ fi
+ fi
+ HOST_PWD=`pwd -P`
+ HOST_PWD=${HOST_PWD/$WSL_ROOT//}
+elif [ -n "$MSYS" ]; then
+ HOST_PWD=$PWD
+ HOST_PWD=${HOST_PWD/\//}
+ HOST_PWD=${HOST_PWD/\//:\/}
+elif [ -n "$CYGWIN" ]; then
+ for f in pwd readlink cygpath ; do
+ test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ;
+ done ;
+ HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ;
+else
+ HOST_PWD=$PWD
+ [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD)
+fi
+
+# Mount Additional Volumes
+if [ -z "$SSH_DIR" ]; then
+ SSH_DIR="$HOME/.ssh"
+fi
+
+HOST_VOLUMES=
+if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then
+ if test -n "${CYGWIN}" ; then
+ HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ;
+ else
+ HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ;
+ fi ;
+fi
+
+#------------------------------------------------------------------------------
+# Now, finally, run the command in a container
+#
+TTY_ARGS=
+tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti
+CONTAINER_NAME=dockcross_$RANDOM
+$OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \
+ -v "$HOST_PWD":/work \
+ $HOST_VOLUMES \
+ "${USER_IDS[@]}" \
+ $FINAL_ARGS \
+ $FINAL_IMAGE "$@"
+run_exit_code=$?
+
+# Attempt to delete container
+rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1)
+rm_exit_code=$?
+if [[ $rm_exit_code != 0 ]]; then
+ if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then
+ : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/
+ else
+ echo "$rm_output"
+ exit $rm_exit_code
+ fi
+fi
+
+exit $run_exit_code
+
+################################################################################
+#
+# This image is not intended to be run manually.
+#
+# To create a dockcross helper script for the
+# dockcross/linux-riscv64:latest image, run:
+#
+# docker run --rm dockcross/linux-riscv64:latest > dockcross-linux-riscv64-latest
+# chmod +x dockcross-linux-riscv64-latest
+#
+# You may then wish to move the dockcross script to your PATH.
+#
+################################################################################
=====================================
pom.xml
=====================================
@@ -4,16 +4,17 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
- <version>3.45.2.0</version>
+ <version>3.46.1.3</version>
<name>SQLite JDBC</name>
<description>SQLite JDBC library</description>
<url>https://github.com/xerial/sqlite-jdbc</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <junit.version>5.10.2</junit.version>
- <surefire.version>3.2.5</surefire.version>
- <graalvm.version>23.1.2</graalvm.version>
+ <junit.version>5.11.0</junit.version>
+ <surefire.version>3.5.0</surefire.version>
+ <archunit.version>1.3.0</archunit.version>
+ <graalvm.version>24.1.0</graalvm.version>
<java9.sourceDirectory>${project.basedir}/src/main/java9</java9.sourceDirectory>
</properties>
@@ -94,13 +95,13 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
- <version>3.4.0</version>
+ <version>3.5.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
- <version>3.12.1</version>
+ <version>3.13.0</version>
<configuration>
<release>8</release>
</configuration>
@@ -136,7 +137,7 @@
<plugin>
<artifactId>maven-jar-plugin</artifactId>
- <version>3.3.0</version>
+ <version>3.4.2</version>
<configuration>
<!-- Pick the MANIFEST generated by the bundle plugin -->
<archive>
@@ -186,7 +187,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
- <version>1.6.13</version>
+ <version>1.7.0</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
@@ -198,7 +199,7 @@
<plugin>
<groupId>org.jreleaser</groupId>
<artifactId>jreleaser-maven-plugin</artifactId>
- <version>1.11.0</version>
+ <version>1.14.0</version>
<configuration>
<configFile>jreleaser.yml</configFile>
</configuration>
@@ -207,13 +208,13 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
- <version>2.16.2</version>
+ <version>2.17.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>3.4.1</version>
+ <version>3.5.0</version>
<executions>
<execution>
<id>enforce-maven</id>
@@ -284,7 +285,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
- <version>3.2.0</version>
+ <version>3.2.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@@ -298,7 +299,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
- <version>3.6.3</version>
+ <version>3.10.0</version>
<configuration>
<sourcepath>src/main/java</sourcepath>
<additionalOptions>-Xdoclint:none</additionalOptions>
@@ -316,7 +317,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
- <version>3.3.0</version>
+ <version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
@@ -337,7 +338,7 @@
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
- <version>0.10.1</version>
+ <version>0.10.3</version>
<extensions>true</extensions>
<executions>
<execution>
@@ -352,13 +353,8 @@
<fallback>false</fallback>
<verbose>true</verbose>
<buildArgs>
- <!--
- ArchUnit tests don't run in native-image tests.
- Remove the ArchUnit JUnit Engine from the ServiceLoader.
- -->
- <buildArg>
- -H:ServiceLoaderFeatureExcludeServiceProviders=com.tngtech.archunit.junit.internal.ArchUnitTestEngine
- </buildArg>
+ <!-- required to allow junit-pioneer to compile with strict image heap enabled -->
+ <arg>--initialize-at-build-time=org.junitpioneer.jupiter.issue.IssueExtensionExecutionListener</arg>
</buildArgs>
</configuration>
</plugin>
@@ -371,13 +367,30 @@
<excludes>
<!-- Cannot run in native mode, classes under test cannot be found, class path is empty -->
<exclude>**/MultipleClassLoaderTest.java</exclude>
- <!-- Not needed -->
- <exclude>**/architecture/*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.tngtech.archunit</groupId>
+ <artifactId>archunit-junit5</artifactId>
+ <version>${archunit.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <!--
+ ArchUnit tests don't run in native-image tests.
+ Remove the ArchUnit JUnit Engine entirely from the dependency graph thus from the ServiceLoader.
+ -->
+ <exclusion>
+ <groupId>com.tngtech.archunit</groupId>
+ <artifactId>archunit-junit5-engine</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
</profile>
<profile>
<id>native-exported</id>
@@ -402,6 +415,7 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
+ <optional>true</optional>
</dependency>
<!--
This dependency makes compilation on non-GraalVM versions possible.
@@ -423,7 +437,7 @@
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
- <version>3.25.3</version>
+ <version>3.26.3</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -445,13 +459,13 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
- <version>5.11.0</version>
+ <version>5.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
- <version>1.2.1</version>
+ <version>${archunit.version}</version>
<scope>test</scope>
</dependency>
<!-- Required by archunit -->
=====================================
src/main/java/org/sqlite/JDBC.java
=====================================
@@ -18,12 +18,12 @@ package org.sqlite;
import java.sql.*;
import java.util.Properties;
-import java.util.logging.Logger;
-import org.slf4j.LoggerFactory;
import org.sqlite.jdbc4.JDBC4Connection;
+import org.sqlite.util.Logger;
+import org.sqlite.util.LoggerFactory;
public class JDBC implements Driver {
- private static final org.slf4j.Logger logger = LoggerFactory.getLogger(JDBC.class);
+ private static final Logger logger = LoggerFactory.getLogger(JDBC.class);
public static final String PREFIX = "jdbc:sqlite:";
static {
@@ -49,7 +49,7 @@ public class JDBC implements Driver {
return false;
}
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO
return null;
}
=====================================
src/main/java/org/sqlite/SQLiteConfig.java
=====================================
@@ -188,6 +188,7 @@ public class SQLiteConfig {
// exclude this "fake" pragma from execution
pragmaParams.remove(Pragma.JDBC_EXPLICIT_READONLY.pragmaName);
+ pragmaParams.remove(Pragma.JDBC_GET_GENERATED_KEYS.pragmaName);
Statement stat = conn.createStatement();
try {
@@ -330,6 +331,9 @@ public class SQLiteConfig {
defaultConnectionConfig.getDateStringFormat());
pragmaTable.setProperty(
Pragma.JDBC_EXPLICIT_READONLY.pragmaName, this.explicitReadOnly ? "true" : "false");
+ pragmaTable.setProperty(
+ Pragma.JDBC_GET_GENERATED_KEYS.pragmaName,
+ defaultConnectionConfig.isGetGeneratedKeys() ? "true" : "false");
return pragmaTable;
}
@@ -349,7 +353,9 @@ public class SQLiteConfig {
return result;
}
- private static final String[] OnOff = new String[] {"true", "false"};
+ static class OnOff {
+ private static final String[] Values = new String[] {"true", "false"};
+ }
static final Set<String> pragmaSet = new TreeSet<String>();
@@ -377,11 +383,14 @@ public class SQLiteConfig {
// Parameters requiring SQLite3 API invocation
OPEN_MODE("open_mode", "Database open-mode flag", null),
- SHARED_CACHE("shared_cache", "Enable SQLite Shared-Cache mode, native driver only", OnOff),
+ SHARED_CACHE(
+ "shared_cache",
+ "Enable SQLite Shared-Cache mode, native driver only",
+ OnOff.Values),
LOAD_EXTENSION(
"enable_load_extension",
"Enable SQLite load_extension() function, native driver only",
- OnOff),
+ OnOff.Values),
// Pragmas that can be set after opening the database
CACHE_SIZE(
@@ -395,24 +404,25 @@ public class SQLiteConfig {
CASE_SENSITIVE_LIKE(
"case_sensitive_like",
"Installs a new application-defined LIKE function that is either case sensitive or insensitive depending on the value",
- OnOff),
- COUNT_CHANGES("count_changes", "Deprecated", OnOff),
+ OnOff.Values),
+ COUNT_CHANGES("count_changes", "Deprecated", OnOff.Values),
DEFAULT_CACHE_SIZE("default_cache_size", "Deprecated", null),
DEFER_FOREIGN_KEYS(
"defer_foreign_keys",
"When the defer_foreign_keys PRAGMA is on, enforcement of all foreign key constraints is delayed until the outermost transaction is committed. The defer_foreign_keys pragma defaults to OFF so that foreign key constraints are only deferred if they are created as \"DEFERRABLE INITIALLY DEFERRED\". The defer_foreign_keys pragma is automatically switched off at each COMMIT or ROLLBACK. Hence, the defer_foreign_keys pragma must be separately enabled for each transaction. This pragma is only meaningful if foreign key constraints are enabled, of course.",
- OnOff),
- EMPTY_RESULT_CALLBACKS("empty_result_callback", "Deprecated", OnOff),
+ OnOff.Values),
+ EMPTY_RESULT_CALLBACKS("empty_result_callback", "Deprecated", OnOff.Values),
ENCODING(
"encoding",
"Set the encoding that the main database will be created with if it is created by this session",
toStringArray(Encoding.values())),
- FOREIGN_KEYS("foreign_keys", "Set the enforcement of foreign key constraints", OnOff),
- FULL_COLUMN_NAMES("full_column_names", "Deprecated", OnOff),
+ FOREIGN_KEYS(
+ "foreign_keys", "Set the enforcement of foreign key constraints", OnOff.Values),
+ FULL_COLUMN_NAMES("full_column_names", "Deprecated", OnOff.Values),
FULL_SYNC(
"fullsync",
"Whether or not the F_FULLFSYNC syncing method is used on systems that support it. Only Mac OS X supports F_FULLFSYNC.",
- OnOff),
+ OnOff.Values),
INCREMENTAL_VACUUM(
"incremental_vacuum",
"Causes up to N pages to be removed from the freelist. The database file is truncated by the same amount. The incremental_vacuum pragma has no effect if the database is not in auto_vacuum=incremental mode or if there are no pages on the freelist. If there are fewer than N pages on the freelist, or if N is less than 1, or if the \"(N)\" argument is omitted, then the entire freelist is cleared.",
@@ -425,8 +435,8 @@ public class SQLiteConfig {
"journal_size_limit",
"Limit the size of rollback-journal and WAL files left in the file-system after transactions or checkpoints",
null),
- LEGACY_ALTER_TABLE("legacy_alter_table", "Use legacy alter table behavior", OnOff),
- LEGACY_FILE_FORMAT("legacy_file_format", "No-op", OnOff),
+ LEGACY_ALTER_TABLE("legacy_alter_table", "Use legacy alter table behavior", OnOff.Values),
+ LEGACY_FILE_FORMAT("legacy_file_format", "No-op", OnOff.Values),
LOCKING_MODE(
"locking_mode",
"Set the database connection locking-mode",
@@ -437,17 +447,18 @@ public class SQLiteConfig {
null),
MAX_PAGE_COUNT(
"max_page_count", "Set the maximum number of pages in the database file", null),
- READ_UNCOMMITTED("read_uncommitted", "Set READ UNCOMMITTED isolation", OnOff),
- RECURSIVE_TRIGGERS("recursive_triggers", "Set the recursive trigger capability", OnOff),
+ READ_UNCOMMITTED("read_uncommitted", "Set READ UNCOMMITTED isolation", OnOff.Values),
+ RECURSIVE_TRIGGERS(
+ "recursive_triggers", "Set the recursive trigger capability", OnOff.Values),
REVERSE_UNORDERED_SELECTS(
"reverse_unordered_selects",
"When enabled, this PRAGMA causes many SELECT statements without an ORDER BY clause to emit their results in the reverse order from what they normally would",
- OnOff),
+ OnOff.Values),
SECURE_DELETE(
"secure_delete",
"When secure_delete is on, SQLite overwrites deleted content with zeros",
new String[] {"true", "false", "fast"}),
- SHORT_COLUMN_NAMES("short_column_names", "Deprecated", OnOff),
+ SHORT_COLUMN_NAMES("short_column_names", "Deprecated", OnOff.Values),
SYNCHRONOUS(
"synchronous",
"Set the \"synchronous\" flag",
@@ -535,7 +546,9 @@ public class SQLiteConfig {
// extensions: "fake" pragmas to allow conformance with JDBC
JDBC_EXPLICIT_READONLY(
- "jdbc.explicit_readonly", "Set explicit read only transactions", null);
+ "jdbc.explicit_readonly", "Set explicit read only transactions", null),
+ JDBC_GET_GENERATED_KEYS(
+ "jdbc.get_generated_keys", "Enable retrieval of generated keys", OnOff.Values);
public final String pragmaName;
public final String[] choices;
@@ -555,6 +568,20 @@ public class SQLiteConfig {
this.choices = choices;
}
+ /**
+ * Convert the given enum values to a string array
+ *
+ * @param list Array if PragmaValue.
+ * @return String array of Enum values
+ */
+ private static String[] toStringArray(PragmaValue[] list) {
+ String[] result = new String[list.length];
+ for (int i = 0; i < list.length; i++) {
+ result[i] = list[i].getValue();
+ }
+ return result;
+ }
+
public final String getPragmaName() {
return pragmaName;
}
@@ -700,20 +727,6 @@ public class SQLiteConfig {
public String getValue();
}
- /**
- * Convert the given enum values to a string array
- *
- * @param list Array if PragmaValue.
- * @return String array of Enum values
- */
- private static String[] toStringArray(PragmaValue[] list) {
- String[] result = new String[list.length];
- for (int i = 0; i < list.length; i++) {
- result[i] = list[i].getValue();
- }
- return result;
- }
-
public enum Encoding implements PragmaValue {
UTF8("'UTF-8'"),
UTF16("'UTF-16'"),
@@ -1176,4 +1189,12 @@ public class SQLiteConfig {
public int getBusyTimeout() {
return busyTimeout;
}
+
+ public boolean isGetGeneratedKeys() {
+ return this.defaultConnectionConfig.isGetGeneratedKeys();
+ }
+
+ public void setGetGeneratedKeys(boolean generatedKeys) {
+ this.defaultConnectionConfig.setGetGeneratedKeys(generatedKeys);
+ }
}
=====================================
src/main/java/org/sqlite/SQLiteConnectionConfig.java
=====================================
@@ -19,6 +19,7 @@ public class SQLiteConnectionConfig implements Cloneable {
private int transactionIsolation = Connection.TRANSACTION_SERIALIZABLE;
private SQLiteConfig.TransactionMode transactionMode = SQLiteConfig.TransactionMode.DEFERRED;
private boolean autoCommit = true;
+ private boolean getGeneratedKeys = true;
public static SQLiteConnectionConfig fromPragmaTable(Properties pragmaTable) {
return new SQLiteConnectionConfig(
@@ -38,7 +39,10 @@ public class SQLiteConnectionConfig implements Cloneable {
pragmaTable.getProperty(
SQLiteConfig.Pragma.TRANSACTION_MODE.pragmaName,
SQLiteConfig.TransactionMode.DEFERRED.name())),
- true);
+ true,
+ Boolean.parseBoolean(
+ pragmaTable.getProperty(
+ SQLiteConfig.Pragma.JDBC_GET_GENERATED_KEYS.pragmaName, "true")));
}
public SQLiteConnectionConfig(
@@ -47,13 +51,15 @@ public class SQLiteConnectionConfig implements Cloneable {
String dateStringFormat,
int transactionIsolation,
SQLiteConfig.TransactionMode transactionMode,
- boolean autoCommit) {
+ boolean autoCommit,
+ boolean getGeneratedKeys) {
setDateClass(dateClass);
setDatePrecision(datePrecision);
setDateStringFormat(dateStringFormat);
setTransactionIsolation(transactionIsolation);
setTransactionMode(transactionMode);
setAutoCommit(autoCommit);
+ setGetGeneratedKeys(getGeneratedKeys);
}
public SQLiteConnectionConfig copyConfig() {
@@ -63,7 +69,8 @@ public class SQLiteConnectionConfig implements Cloneable {
dateStringFormat,
transactionIsolation,
transactionMode,
- autoCommit);
+ autoCommit,
+ getGeneratedKeys);
}
public long getDateMultiplier() {
@@ -124,8 +131,16 @@ public class SQLiteConnectionConfig implements Cloneable {
this.transactionMode = transactionMode;
}
+ public boolean isGetGeneratedKeys() {
+ return getGeneratedKeys;
+ }
+
+ public void setGetGeneratedKeys(boolean getGeneratedKeys) {
+ this.getGeneratedKeys = getGeneratedKeys;
+ }
+
private static final Map<SQLiteConfig.TransactionMode, String> beginCommandMap =
- new EnumMap<SQLiteConfig.TransactionMode, String>(SQLiteConfig.TransactionMode.class);
+ new EnumMap<>(SQLiteConfig.TransactionMode.class);
static {
beginCommandMap.put(SQLiteConfig.TransactionMode.DEFERRED, "begin;");
=====================================
src/main/java/org/sqlite/SQLiteDataSource.java
=====================================
@@ -437,6 +437,15 @@ public class SQLiteDataSource implements DataSource {
config.setTransactionMode(transactionMode);
}
+ /**
+ * Configure where generated keys will be retrieved for this database.
+ *
+ * @param generatedKeys true to retrieve generated keys
+ */
+ public void setGetGeneratedKeys(boolean generatedKeys) {
+ config.setGetGeneratedKeys(generatedKeys);
+ }
+
/**
* Sets the value of the user-version. It is a big-endian 32-bit signed integer stored in the
* database header at offset 60.
=====================================
src/main/java/org/sqlite/SQLiteJDBCLoader.java
=====================================
@@ -39,9 +39,9 @@ import java.util.List;
import java.util.Properties;
import java.util.UUID;
import java.util.stream.Stream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sqlite.util.LibraryLoaderUtil;
+import org.sqlite.util.Logger;
+import org.sqlite.util.LoggerFactory;
import org.sqlite.util.OSInfo;
import org.sqlite.util.StringUtils;
=====================================
src/main/java/org/sqlite/core/CoreStatement.java
=====================================
@@ -181,10 +181,12 @@ public abstract class CoreStatement implements Codes {
* block.
*/
public void updateGeneratedKeys() throws SQLException {
- clearGeneratedKeys();
- if (sql != null && INSERT_PATTERN.matcher(sql).find()) {
- generatedKeysStat = conn.createStatement();
- generatedKeysRs = generatedKeysStat.executeQuery("SELECT last_insert_rowid();");
+ if (conn.getConnectionConfig().isGetGeneratedKeys()) {
+ clearGeneratedKeys();
+ if (sql != null && INSERT_PATTERN.matcher(sql).find()) {
+ generatedKeysStat = conn.createStatement();
+ generatedKeysRs = generatedKeysStat.executeQuery("SELECT last_insert_rowid();");
+ }
}
}
=====================================
src/main/java/org/sqlite/core/NativeDB.java
=====================================
@@ -19,14 +19,14 @@ package org.sqlite.core;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sqlite.BusyHandler;
import org.sqlite.Collation;
import org.sqlite.Function;
import org.sqlite.ProgressHandler;
import org.sqlite.SQLiteConfig;
import org.sqlite.SQLiteJDBCLoader;
+import org.sqlite.util.Logger;
+import org.sqlite.util.LoggerFactory;
/** This class provides a thin JNI layer over the SQLite3 C API. */
public final class NativeDB extends DB {
=====================================
src/main/java/org/sqlite/jdbc3/JDBC3DatabaseMetaData.java
=====================================
@@ -21,12 +21,12 @@ import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sqlite.SQLiteConnection;
import org.sqlite.core.CoreDatabaseMetaData;
import org.sqlite.core.CoreStatement;
import org.sqlite.jdbc3.JDBC3DatabaseMetaData.ImportedKeyFinder.ForeignKey;
+import org.sqlite.util.Logger;
+import org.sqlite.util.LoggerFactory;
import org.sqlite.util.QueryUtils;
import org.sqlite.util.StringUtils;
@@ -1078,7 +1078,10 @@ public abstract class JDBC3DatabaseMetaData extends CoreDatabaseMetaData {
colType = colType.substring(0, iStartOfDimension).trim();
}
- int colGenerated = "2".equals(colHidden) ? 1 : 0;
+ int colGenerated = 0;
+ if ("2".equals(colHidden) || "3".equals(colHidden)) {
+ colGenerated = 1;
+ }
sql.append("select ")
.append(i + 1)
=====================================
src/main/java/org/sqlite/jdbc3/JDBC3Statement.java
=====================================
@@ -8,14 +8,14 @@ import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sqlite.ExtendedCommand;
import org.sqlite.ExtendedCommand.SQLExtension;
import org.sqlite.SQLiteConnection;
import org.sqlite.core.CoreStatement;
import org.sqlite.core.DB;
import org.sqlite.core.DB.ProgressObserver;
+import org.sqlite.util.Logger;
+import org.sqlite.util.LoggerFactory;
public abstract class JDBC3Statement extends CoreStatement {
=====================================
src/main/java/org/sqlite/util/Logger.java
=====================================
@@ -0,0 +1,18 @@
+package org.sqlite.util;
+
+/** A simple internal Logger interface. */
+public interface Logger {
+ boolean isTraceEnabled();
+
+ void trace(String format, Object o1, Object o2);
+
+ void info(String format, Object o1, Object o2);
+
+ void warn(String msg);
+
+ void error(String message, Throwable t);
+
+ void error(String format, Object o1, Throwable t);
+
+ void error(String format, Object o1, Object o2, Throwable t);
+}
=====================================
src/main/java/org/sqlite/util/LoggerFactory.java
=====================================
@@ -0,0 +1,130 @@
+package org.sqlite.util;
+
+import java.text.MessageFormat;
+
+/**
+ * A factory for {@link Logger} instances that uses SLF4J if present, falling back on a
+ * java.util.logging implementation otherwise.
+ */
+public class LoggerFactory {
+ static final boolean USE_SLF4J;
+
+ static {
+ boolean useSLF4J;
+ try {
+ Class.forName("org.slf4j.Logger");
+ useSLF4J = true;
+ } catch (Exception e) {
+ useSLF4J = false;
+ }
+ USE_SLF4J = useSLF4J;
+ }
+
+ /**
+ * Get a {@link Logger} instance for the given host class.
+ *
+ * @param hostClass the host class from which log messages will be issued
+ * @return a Logger
+ */
+ public static Logger getLogger(Class<?> hostClass) {
+ if (USE_SLF4J) {
+ return new SLF4JLogger(hostClass);
+ }
+
+ return new JDKLogger(hostClass);
+ }
+
+ private static class JDKLogger implements Logger {
+ final java.util.logging.Logger logger;
+
+ public JDKLogger(Class<?> hostClass) {
+ logger = java.util.logging.Logger.getLogger(hostClass.getCanonicalName());
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return logger.isLoggable(java.util.logging.Level.FINEST);
+ }
+
+ @Override
+ public void trace(String format, Object o1, Object o2) {
+ if (logger.isLoggable(java.util.logging.Level.FINEST)) {
+ logger.log(java.util.logging.Level.FINEST, MessageFormat.format(format, o1, o2));
+ }
+ }
+
+ @Override
+ public void info(String format, Object o1, Object o2) {
+ if (logger.isLoggable(java.util.logging.Level.INFO)) {
+ logger.log(java.util.logging.Level.INFO, MessageFormat.format(format, o1, o2));
+ }
+ }
+
+ @Override
+ public void warn(String msg) {
+ logger.log(java.util.logging.Level.WARNING, msg);
+ }
+
+ @Override
+ public void error(String message, Throwable t) {
+ logger.log(java.util.logging.Level.SEVERE, message, t);
+ }
+
+ @Override
+ public void error(String format, Object o1, Throwable t) {
+ if (logger.isLoggable(java.util.logging.Level.SEVERE)) {
+ logger.log(java.util.logging.Level.SEVERE, MessageFormat.format(format, o1), t);
+ }
+ }
+
+ @Override
+ public void error(String format, Object o1, Object o2, Throwable t) {
+ if (logger.isLoggable(java.util.logging.Level.SEVERE)) {
+ logger.log(java.util.logging.Level.SEVERE, MessageFormat.format(format, o1, o2), t);
+ }
+ }
+ }
+
+ private static class SLF4JLogger implements Logger {
+ final org.slf4j.Logger logger;
+
+ SLF4JLogger(Class<?> hostClass) {
+ logger = org.slf4j.LoggerFactory.getLogger(hostClass);
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return logger.isTraceEnabled();
+ }
+
+ @Override
+ public void trace(String format, Object o1, Object o2) {
+ logger.trace(format, o1, o2);
+ }
+
+ @Override
+ public void info(String format, Object o1, Object o2) {
+ logger.info(format, o1, o2);
+ }
+
+ @Override
+ public void warn(String msg) {
+ logger.warn(msg);
+ }
+
+ @Override
+ public void error(String message, Throwable t) {
+ logger.error(message, t);
+ }
+
+ @Override
+ public void error(String format, Object o1, Throwable t) {
+ logger.error(format, o1, t);
+ }
+
+ @Override
+ public void error(String format, Object o1, Object o2, Throwable t) {
+ logger.error(format, o1, o2, t);
+ }
+ }
+}
=====================================
src/main/java/org/sqlite/util/OSInfo.java
=====================================
@@ -31,8 +31,6 @@ import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Locale;
import java.util.stream.Stream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Provides OS name and architecture name.
@@ -49,6 +47,7 @@ public class OSInfo {
public static final String IA64 = "ia64";
public static final String PPC = "ppc";
public static final String PPC64 = "ppc64";
+ public static final String RISCV64 = "riscv64";
static {
// x86 mappings
@@ -88,6 +87,8 @@ public class OSInfo {
archMapping.put("power_rs64", PPC64);
archMapping.put("ppc64el", PPC64);
archMapping.put("ppc64le", PPC64);
+
+ archMapping.put(RISCV64, RISCV64);
}
public static void main(String[] args) {
@@ -191,8 +192,14 @@ public class OSInfo {
// Use armv5, soft-float ABI
return "arm";
} else if (armType.startsWith("aarch64")) {
- // Use arm64
- return "aarch64";
+ boolean is32bitJVM = "32".equals(System.getProperty("sun.arch.data.model"));
+ if (is32bitJVM) {
+ // An aarch64 architecture should support armv7
+ return "armv7";
+ } else {
+ // Use arm64
+ return "aarch64";
+ }
}
// Java 1.8 introduces a system property to determine armel or armhf
=====================================
src/main/java9/org/sqlite/nativeimage/SqliteJdbcFeature.java
=====================================
@@ -10,6 +10,7 @@ import org.sqlite.core.NativeDB;
import org.sqlite.jdbc3.JDBC3DatabaseMetaData;
import org.sqlite.util.LibraryLoaderUtil;
import org.sqlite.util.OSInfo;
+import org.sqlite.util.ProcessRunner;
import java.io.IOException;
import java.io.InputStream;
@@ -27,6 +28,7 @@ public class SqliteJdbcFeature implements Feature {
RuntimeClassInitialization.initializeAtBuildTime(SQLiteJDBCLoader.VersionHolder.class);
RuntimeClassInitialization.initializeAtBuildTime(JDBC3DatabaseMetaData.class);
RuntimeClassInitialization.initializeAtBuildTime(OSInfo.class);
+ RuntimeClassInitialization.initializeAtBuildTime(ProcessRunner.class);
RuntimeClassInitialization.initializeAtBuildTime(LibraryLoaderUtil.class);
a.registerReachabilityHandler(
this::nativeDbReachable, method(SQLiteJDBCLoader.class, "initialize"));
=====================================
src/test/java/org/sqlite/DBMetaDataTest.java
=====================================
@@ -18,6 +18,7 @@ import java.util.Map;
import java.util.Properties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledInNativeImage;
@@ -490,6 +491,29 @@ public class DBMetaDataTest {
assertThat(rs.next()).isFalse();
}
+ @Test
+ @DisplayName(
+ "Issue #1132 - Generated columns with stored in SQLite are not marked as generated")
+ public void getColumnsIncludingGeneratedStored() throws SQLException {
+ stat.executeUpdate(
+ "create table foo("
+ + "\n"
+ + " id integer primary key,"
+ + "\n"
+ + " bar int not null generated always as (id + 1) stored"
+ + "\n"
+ + ");");
+
+ ResultSet rs = meta.getColumns(null, null, "foo", "%");
+ assertThat(rs.next()).isTrue();
+ assertThat(rs.getString(4)).as("first column is named 'id'").isEqualTo("id");
+ assertThat(rs.getString(24)).as("first column is generated").isEqualTo("NO");
+ assertThat(rs.next()).isTrue();
+ assertThat(rs.getString(4)).as("second column is named 'bar'").isEqualTo("bar");
+ assertThat(rs.getString(24)).as("second column is generated").isEqualTo("YES");
+ assertThat(rs.next()).isFalse();
+ }
+
@Test
public void getColumnsWithEscape() throws SQLException {
stat.executeUpdate("create table wildcard(col1 integer, co_1 integer, 'co%1' integer)");
=====================================
src/test/java/org/sqlite/MultipleClassLoaderTest.java
=====================================
@@ -48,7 +48,12 @@ import java.util.jar.JarOutputStream;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
+ at DisabledIfEnvironmentVariable(
+ named = "SKIP_TEST_MULTIARCH",
+ matches = "true",
+ disabledReason = "Those tests would fail when ran on a multi-arch image")
public class MultipleClassLoaderTest {
private Connection connection = null;
=====================================
src/test/java/org/sqlite/PrepStmtTest.java
=====================================
@@ -81,6 +81,36 @@ public class PrepStmtTest {
rs.close();
}
+ @Test
+ public void pragmaGetGeneratedKeys() throws SQLException {
+ SQLiteConnection connection =
+ (SQLiteConnection)
+ DriverManager.getConnection(
+ "jdbc:sqlite::memory:?jdbc.get_generated_keys=false");
+ assertThat(connection.getConnectionConfig().isGetGeneratedKeys()).isFalse();
+ }
+
+ @Test
+ public void updateWithoutGeneratedKeys() throws SQLException {
+ Connection conn =
+ DriverManager.getConnection("jdbc:sqlite::memory:?jdbc.get_generated_keys=false");
+
+ assertThat(conn.prepareStatement("create table s1 (c1);").executeUpdate()).isEqualTo(0);
+ PreparedStatement prep = conn.prepareStatement("insert into s1 values (?);");
+ prep.setInt(1, 3);
+ assertThat(prep.executeUpdate()).isEqualTo(1);
+ assertThat(prep.getResultSet()).isNull();
+ prep.setInt(1, 5);
+ assertThat(prep.executeUpdate()).isEqualTo(1);
+ prep.setInt(1, 7);
+ assertThat(prep.executeUpdate()).isEqualTo(1);
+
+ ResultSet rsgk = prep.getGeneratedKeys();
+ assertThat(rsgk.next()).isFalse();
+ rsgk.close();
+ prep.close();
+ }
+
@Test
public void multiUpdate() throws SQLException {
stat.executeUpdate("create table test (c1);");
=====================================
src/test/java/org/sqlite/SQLiteConfigTest.java
=====================================
@@ -1,9 +1,12 @@
package org.sqlite;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.*;
+import java.util.HashSet;
import java.util.Properties;
+import java.util.Set;
import org.junit.jupiter.api.Test;
+import org.sqlite.SQLiteConfig.Pragma;
public class SQLiteConfigTest {
@@ -15,6 +18,7 @@ public class SQLiteConfigTest {
config.setDateStringFormat("yyyy/mm/dd");
config.setDatePrecision("seconds");
config.setDateClass("real");
+ config.setGetGeneratedKeys(false);
Properties properties = config.toProperties();
@@ -24,6 +28,8 @@ public class SQLiteConfigTest {
.isEqualTo(SQLiteConfig.DatePrecision.SECONDS.name());
assertThat(properties.getProperty(SQLiteConfig.Pragma.DATE_CLASS.getPragmaName()))
.isEqualTo(SQLiteConfig.DateClass.REAL.name());
+ assertThat(properties.getProperty(Pragma.JDBC_GET_GENERATED_KEYS.getPragmaName()))
+ .isEqualTo("false");
}
@Test
@@ -50,4 +56,14 @@ public class SQLiteConfigTest {
.isEqualTo("100");
assertThat(config.getBusyTimeout()).isEqualTo(100);
}
+
+ @Test
+ public void pragmaSet() {
+ Set<String> expectedPragmaSet = new HashSet<>();
+ for (Pragma v : SQLiteConfig.Pragma.values()) {
+ expectedPragmaSet.add(v.pragmaName);
+ }
+
+ assertThat(SQLiteConfig.pragmaSet).isEqualTo(expectedPragmaSet);
+ }
}
=====================================
src/test/java/org/sqlite/SQLiteDataSourceTest.java
=====================================
@@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.nio.ByteOrder;
import java.sql.Connection;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -92,4 +93,36 @@ public class SQLiteDataSourceTest {
.isEqualTo("1234");
assertThat(ds.getConfig().getBusyTimeout()).isEqualTo(1234);
}
+
+ @Test
+ public void setGetGeneratedKeys() throws SQLException {
+ final SQLiteDataSource ds = new SQLiteDataSource();
+ ds.setGetGeneratedKeys(false);
+ assertThat(
+ ds.getConfig()
+ .toProperties()
+ .getProperty(
+ SQLiteConfig.Pragma.JDBC_GET_GENERATED_KEYS.pragmaName))
+ .isEqualTo("false");
+ assertThat(ds.getConfig().isGetGeneratedKeys()).isEqualTo(false);
+ assertThat(
+ ((SQLiteConnection) ds.getConnection())
+ .getConnectionConfig()
+ .isGetGeneratedKeys())
+ .isFalse();
+
+ ds.setGetGeneratedKeys(true);
+ assertThat(
+ ds.getConfig()
+ .toProperties()
+ .getProperty(
+ SQLiteConfig.Pragma.JDBC_GET_GENERATED_KEYS.pragmaName))
+ .isEqualTo("true");
+ assertThat(ds.getConfig().isGetGeneratedKeys()).isEqualTo(true);
+ assertThat(
+ ((SQLiteConnection) ds.getConnection())
+ .getConnectionConfig()
+ .isGetGeneratedKeys())
+ .isTrue();
+ }
}
=====================================
src/test/java/org/sqlite/StatementTest.java
=====================================
@@ -1,8 +1,6 @@
package org.sqlite;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatNoException;
+import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.data.Offset.offset;
import java.lang.reflect.Method;
@@ -351,6 +349,23 @@ public class StatementTest {
assertThat(rs).isNotNull();
assertThat(rs.next()).isFalse();
stat2.close();
+
+ // disable then re-enable generated keys retrieval
+ try {
+ ((SQLiteConnection) conn).getConnectionConfig().setGetGeneratedKeys(false);
+ stat.executeUpdate("insert into t1 (v) values ('red');");
+ rs = stat.getGeneratedKeys();
+ assertThat(rs.next()).isFalse();
+
+ ((SQLiteConnection) conn).getConnectionConfig().setGetGeneratedKeys(true);
+
+ stat.executeUpdate("insert into t1 (v) values ('red');");
+ rs = stat.getGeneratedKeys();
+ assertThat(rs.next()).isTrue();
+ rs.close();
+ } finally {
+ ((SQLiteConnection) conn).getConnectionConfig().setGetGeneratedKeys(true);
+ }
}
@Test
=====================================
src/test/java/org/sqlite/architecture/CodingRulesTest.java
=====================================
@@ -1,6 +1,7 @@
package org.sqlite.architecture;
import static com.tngtech.archunit.base.DescribedPredicate.not;
+import static com.tngtech.archunit.core.domain.JavaClass.Predicates.belongToAnyOf;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.equivalentTo;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
@@ -14,15 +15,26 @@ import com.tngtech.archunit.core.domain.properties.HasOwner;
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.conditions.ArchConditions;
import java.sql.DriverManager;
+import org.sqlite.util.LoggerFactory;
import org.sqlite.util.OSInfo;
@AnalyzeClasses(
packages = "org.sqlite",
importOptions = {ImportOption.DoNotIncludeTests.class})
class CodingRulesTest {
+ public static final ArchCondition<JavaClass> USE_SLF4J_LOGGING;
+
+ static {
+ USE_SLF4J_LOGGING =
+ ArchConditions.dependOnClassesThat(
+ com.tngtech.archunit.core.domain.JavaClass.Predicates
+ .resideInAPackage("org.slf4j"))
+ .as("use SLF4J");
+ }
@ArchTest
void no_access_to_standard_streams(JavaClasses importedClasses) {
@@ -35,7 +47,12 @@ class CodingRulesTest {
@ArchTest private final ArchRule no_jodatime = NO_CLASSES_SHOULD_USE_JODATIME;
- @ArchTest private final ArchRule no_java_util_logging = NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;
+ @ArchTest
+ private final ArchRule no_loggers_except_ours =
+ noClasses()
+ .that(not(belongToAnyOf(LoggerFactory.class)))
+ .should(USE_JAVA_UTIL_LOGGING)
+ .orShould(USE_SLF4J_LOGGING);
@ArchTest
private final ArchRule no_driver_manager_println =
=====================================
src/test/java/org/sqlite/util/OSInfoTest.java
=====================================
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.condition.DisabledInNativeImage;
import org.junitpioneer.jupiter.SetSystemProperty;
@DisabledIfEnvironmentVariable(
- named = "SKIP_TEST_OSINFO",
+ named = "SKIP_TEST_MULTIARCH",
matches = "true",
disabledReason = "Those tests would fail when ran on a musl based Linux")
@DisabledInNativeImage
View it on GitLab: https://salsa.debian.org/java-team/xerial-sqlite-jdbc/-/commit/a19678a2379751cb8f674c590744fb26c94407a6
--
View it on GitLab: https://salsa.debian.org/java-team/xerial-sqlite-jdbc/-/commit/a19678a2379751cb8f674c590744fb26c94407a6
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20241009/565422c5/attachment.htm>
More information about the pkg-java-commits
mailing list