Skip to content

Commit

Permalink
Merge branch 'master' into Fix-1141
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurscchan authored Nov 19, 2024
2 parents 5238db5 + da8596c commit 43401a2
Show file tree
Hide file tree
Showing 46 changed files with 362 additions and 71 deletions.
11 changes: 5 additions & 6 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
= SQLite JDBC Driver
:project-version: 3.46.1.0
:project-version: 3.47.0.0

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]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -116,7 +115,7 @@ the following operating systems:
|macOS | |✔ | | | |✔ | |
|Linux (libc) |✔ |✔ |✔ |✔ |✔ |✔ |✔ |✔
|Linux (musl) |✔ |✔ | | | |✔ | |
|Android |✔ |✔ |✔ | | |✔ | |
|Android (API Level 24+) |✔ |✔ |✔ | | |✔ | |
|FreeBSD |✔ |✔ | | | |✔ | |
|===

Expand Down
16 changes: 16 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=3.46.1
version=3.47.0
25 changes: 13 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.46.1.1-SNAPSHOT</version>
<version>3.47.0.1-SNAPSHOT</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.3</junit.version>
<surefire.version>3.3.1</surefire.version>
<junit.version>5.11.3</junit.version>
<surefire.version>3.5.2</surefire.version>
<archunit.version>1.3.0</archunit.version>
<graalvm.version>24.0.2</graalvm.version>
<graalvm.version>24.1.1</graalvm.version>
<java9.sourceDirectory>${project.basedir}/src/main/java9</java9.sourceDirectory>
</properties>

Expand Down Expand Up @@ -95,7 +95,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>3.4.1</version>
<version>3.5.1</version>
</plugin>

<plugin>
Expand Down Expand Up @@ -199,7 +199,7 @@
<plugin>
<groupId>org.jreleaser</groupId>
<artifactId>jreleaser-maven-plugin</artifactId>
<version>1.13.1</version>
<version>1.15.0</version>
<configuration>
<configFile>jreleaser.yml</configFile>
</configuration>
Expand All @@ -208,7 +208,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.17.1</version>
<version>2.18.0</version>
</plugin>

<plugin>
Expand Down Expand Up @@ -285,7 +285,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.5</version>
<version>3.2.7</version>
<executions>
<execution>
<id>sign-artifacts</id>
Expand All @@ -299,7 +299,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.8.0</version>
<version>3.11.1</version>
<configuration>
<sourcepath>src/main/java</sourcepath>
<additionalOptions>-Xdoclint:none</additionalOptions>
Expand Down Expand Up @@ -338,7 +338,7 @@
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.10.2</version>
<version>0.10.3</version>
<extensions>true</extensions>
<executions>
<execution>
Expand Down Expand Up @@ -415,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.
Expand Down Expand Up @@ -452,13 +453,13 @@
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>2.2.0</version>
<version>2.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.12.0</version>
<version>5.14.2</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/sqlite/JDBC.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@

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 {
try {
DriverManager.registerDriver(new JDBC());
} catch (SQLException e) {
logger.error("Could not register driver", e);
logger.error(() -> "Could not register driver", e);
}
}

Expand All @@ -49,7 +49,7 @@ public boolean jdbcCompliant() {
return false;
}

public Logger getParentLogger() throws SQLFeatureNotSupportedException {
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO
return null;
}
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/org/sqlite/SQLiteConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public void apply(Connection conn) throws SQLException {

// 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 {
Expand Down Expand Up @@ -330,6 +331,9 @@ public Properties toProperties() {
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;
}

Expand Down Expand Up @@ -542,7 +546,9 @@ public enum Pragma {

// 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;
Expand Down Expand Up @@ -1183,4 +1189,12 @@ public void setBusyTimeout(int milliseconds) {
public int getBusyTimeout() {
return busyTimeout;
}

public boolean isGetGeneratedKeys() {
return this.defaultConnectionConfig.isGetGeneratedKeys();
}

public void setGetGeneratedKeys(boolean generatedKeys) {
this.defaultConnectionConfig.setGetGeneratedKeys(generatedKeys);
}
}
23 changes: 19 additions & 4 deletions src/main/java/org/sqlite/SQLiteConnectionConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -38,7 +39,10 @@ public static SQLiteConnectionConfig fromPragmaTable(Properties pragmaTable) {
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(
Expand All @@ -47,13 +51,15 @@ public SQLiteConnectionConfig(
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() {
Expand All @@ -63,7 +69,8 @@ public SQLiteConnectionConfig copyConfig() {
dateStringFormat,
transactionIsolation,
transactionMode,
autoCommit);
autoCommit,
getGeneratedKeys);
}

public long getDateMultiplier() {
Expand Down Expand Up @@ -124,8 +131,16 @@ public void setTransactionMode(SQLiteConfig.TransactionMode transactionMode) {
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;");
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/sqlite/SQLiteDataSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,15 @@ public void setTransactionMode(String transactionMode) {
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.
Expand Down
Loading

0 comments on commit 43401a2

Please sign in to comment.