Rename fileName to filePath for clarity

This commit is contained in:
김선우
2025-01-17 04:26:27 +09:00
parent 0819963b2f
commit 3e2e998060
6 changed files with 97 additions and 151 deletions

View File

@@ -15,16 +15,16 @@ import java.util.concurrent.atomic.AtomicBoolean;
* differences between the JDBC specification and the Limbo API.
*/
public abstract class AbstractDB {
private final String url;
private final String fileName;
protected final String url;
protected final String filePath;
private final AtomicBoolean closed = new AtomicBoolean(true);
// Tracer for statements to avoid unfinalized statements on db close.
private final Set<SafeStatementPointer> statementPointerSet = ConcurrentHashMap.newKeySet();
public AbstractDB(String url, String filaName) {
public AbstractDB(String url, String filePath) {
this.url = url;
this.fileName = filaName;
this.filePath = filePath;
}
public boolean isClosed() {
@@ -55,7 +55,7 @@ public abstract class AbstractDB {
* @throws SQLException if a database access error occurs.
*/
public final synchronized void open(int openFlags) throws SQLException {
open0(fileName, openFlags);
open0(filePath, openFlags);
}
protected abstract void open0(String fileName, int openFlags) throws SQLException;
@@ -72,29 +72,36 @@ public abstract class AbstractDB {
}
/**
* Compiles an SQL statement.
* Connects to a database.
*
* @param stmt The SQL statement to compile.
* @throws SQLException if a database access error occurs.
* @return Pointer to the connection.
*/
public final void prepare(CoreStatement stmt) throws SQLException {
if (stmt.sql == null) {
throw new SQLException("Statement must not be null");
}
public abstract long connect() throws SQLException;
// TODO: check whether closing the pointer and replacing stamt.pointer should work atomically using locks etc
final SafeStatementPointer pointer = stmt.getStmtPointer();
if (pointer != null) {
pointer.close();
}
final SafeStatementPointer newPointer = prepare(stmt.sql);
stmt.setStmtPointer(newPointer);
final boolean added = statementPointerSet.add(newPointer);
if (!added) {
throw new IllegalStateException("The pointer is already added to statements set");
}
}
// /**
// * Compiles an SQL statement.
// *
// * @param stmt The SQL statement to compile.
// * @throws SQLException if a database access error occurs.
// */
// public final void prepare(CoreStatement stmt) throws SQLException {
// if (stmt.sql == null) {
// throw new SQLException("Statement must not be null");
// }
//
// // TODO: check whether closing the pointer and replacing stamt.pointer should work atomically using locks etc
// final SafeStatementPointer pointer = stmt.getStmtPointer();
// if (pointer != null) {
// pointer.close();
// }
//
// final SafeStatementPointer newPointer = stmt.connection.prepare(stmt.sql);
// stmt.setStmtPointer(newPointer);
// final boolean added = statementPointerSet.add(newPointer);
// if (!added) {
// throw new IllegalStateException("The pointer is already added to statements set");
// }
// }
/**
* Destroys a statement.
@@ -135,15 +142,6 @@ public abstract class AbstractDB {
*/
public abstract int exec(String sql) throws SQLException;
/**
* Compiles an SQL statement.
*
* @param sql An SQL statement.
* @return A SafeStmtPtr object.
* @throws SQLException if a database access error occurs.
*/
protected abstract SafeStatementPointer prepare(String sql) throws SQLException;
/**
* Destroys a prepared statement.
*
@@ -189,21 +187,4 @@ public abstract class AbstractDB {
// TODO: add implementation
throw new SQLFeatureNotSupportedException();
}
/**
* @param stmt Pointer to the statement.
* @return Number of columns in the result set returned by the prepared statement.
* @throws SQLException
* @see <a
* href="https://www.sqlite.org/c3ref/column_count.html">https://www.sqlite.org/c3ref/column_count.html</a>
*/
public abstract int columnCount(long stmt) throws SQLException;
/**
* @return Number of rows that were changed, inserted or deleted by the last SQL statement
* @throws SQLException
* @see <a
* href="https://www.sqlite.org/c3ref/changes.html">https://www.sqlite.org/c3ref/changes.html</a>
*/
public abstract long changes() throws SQLException;
}

View File

@@ -1,36 +1,38 @@
package org.github.tursodatabase;
package org.github.tursodatabase.core;
import org.github.tursodatabase.core.AbstractDB;
import org.github.tursodatabase.core.LimboDBFactory;
import org.github.tursodatabase.annotations.NativeInvocation;
import org.github.tursodatabase.utils.LimboExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public abstract class LimboConnection implements Connection {
import static org.github.tursodatabase.utils.ByteArrayUtils.stringToUtf8ByteArray;
public abstract class LimboConnection implements Connection {
private static final Logger logger = LoggerFactory.getLogger(LimboConnection.class);
private final long connectionPtr;
private final AbstractDB database;
public LimboConnection(AbstractDB database) {
this.database = database;
}
public LimboConnection(String url, String fileName) throws SQLException {
this(url, fileName, new Properties());
public LimboConnection(String url, String filePath) throws SQLException {
this(url, filePath, new Properties());
}
/**
* Creates a connection to limbo database.
*
* @param url e.g. "jdbc:sqlite:fileName"
* @param fileName path to file
* @param filePath path to file
*/
public LimboConnection(String url, String fileName, Properties properties) throws SQLException {
public LimboConnection(String url, String filePath, Properties properties) throws SQLException {
AbstractDB db = null;
try {
db = open(url, fileName, properties);
db = open(url, filePath, properties);
} catch (Throwable t) {
try {
if (db != null) {
@@ -44,10 +46,11 @@ public abstract class LimboConnection implements Connection {
}
this.database = db;
this.connectionPtr = db.connect();
}
private static AbstractDB open(String url, String fileName, Properties properties) throws SQLException {
return LimboDBFactory.open(url, fileName, properties);
private static AbstractDB open(String url, String filePath, Properties properties) throws SQLException {
return LimboDBFactory.open(url, filePath, properties);
}
protected void checkOpen() throws SQLException {

View File

@@ -4,23 +4,28 @@ package org.github.tursodatabase.core;
import org.github.tursodatabase.LimboErrorCode;
import org.github.tursodatabase.annotations.NativeInvocation;
import org.github.tursodatabase.annotations.VisibleForTesting;
import org.github.tursodatabase.annotations.Nullable;
import org.github.tursodatabase.exceptions.LimboException;
import org.github.tursodatabase.utils.ByteArrayUtils;
import org.github.tursodatabase.utils.LimboExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.concurrent.locks.ReentrantLock;
import static org.github.tursodatabase.utils.ByteArrayUtils.stringToUtf8ByteArray;
/**
* This class provides a thin JNI layer over the SQLite3 C API.
*/
public final class LimboDB extends AbstractDB {
private static final Logger logger = LoggerFactory.getLogger(LimboDB.class);
// Pointer to database instance
private long dbPtr;
private long dbPointer;
private boolean isOpen;
private static boolean isLoaded;
private ReentrantLock dbLock = new ReentrantLock();
static {
if ("The Android Project".equals(System.getProperty("java.vm.vendor"))) {
@@ -46,80 +51,69 @@ public final class LimboDB extends AbstractDB {
/**
* @param url e.g. "jdbc:sqlite:fileName
* @param fileName e.g. path to file
* @param filePath e.g. path to file
*/
public static LimboDB create(String url, String fileName) throws SQLException {
return new LimboDB(url, fileName);
public static LimboDB create(String url, String filePath) throws SQLException {
return new LimboDB(url, filePath);
}
// TODO: receive config as argument
private LimboDB(String url, String fileName) {
super(url, fileName);
private LimboDB(String url, String filePath) {
super(url, filePath);
}
// WRAPPER FUNCTIONS ////////////////////////////////////////////
// TODO: add support for JNI
@Override
protected synchronized native long openUtf8(byte[] file, int openFlags) throws SQLException;
protected native long openUtf8(byte[] file, int openFlags) throws SQLException;
// TODO: add support for JNI
@Override
protected synchronized native void close0() throws SQLException;
protected native void close0() throws SQLException;
@Override
public synchronized int exec(String sql) throws SQLException {
public int exec(String sql) throws SQLException {
// TODO: add implementation
throw new SQLFeatureNotSupportedException();
}
// TODO: add support for JNI
synchronized native int execUtf8(byte[] sqlUtf8) throws SQLException;
native int execUtf8(byte[] sqlUtf8) throws SQLException;
// TODO: add support for JNI
@Override
public native void interrupt();
@Override
protected void open0(String fileName, int openFlags) throws SQLException {
protected void open0(String filePath, int openFlags) throws SQLException {
if (isOpen) {
throw buildLimboException(LimboErrorCode.ETC.code, "Already opened");
throw LimboExceptionUtils.buildLimboException(LimboErrorCode.LIMBO_ETC.code, "Already opened");
}
byte[] fileNameBytes = stringToUtf8ByteArray(fileName);
if (fileNameBytes == null) {
throw buildLimboException(LimboErrorCode.ETC.code, "File name cannot be converted to byteArray. File name: " + fileName);
byte[] filePathBytes = stringToUtf8ByteArray(filePath);
if (filePathBytes == null) {
throw LimboExceptionUtils.buildLimboException(LimboErrorCode.LIMBO_ETC.code, "File name cannot be converted to byteArray. File name: " + filePath);
}
dbPtr = openUtf8(fileNameBytes, openFlags);
dbPointer = openUtf8(filePathBytes, openFlags);
isOpen = true;
}
@Override
protected synchronized SafeStatementPointer prepare(String sql) throws SQLException {
// TODO: add implementation
throw new SQLFeatureNotSupportedException();
public long connect() throws SQLException {
return connect0(ByteArrayUtils.stringToUtf8ByteArray(filePath), dbPointer);
}
private native long connect0(byte[] path, long databasePtr) throws SQLException;
// TODO: add support for JNI
@Override
protected synchronized native int finalize(long stmt);
protected native int finalize(long stmt);
// TODO: add support for JNI
@Override
public synchronized native int step(long stmt);
@Override
public int columnCount(long stmt) throws SQLException {
// TODO
return 0;
}
@Override
public long changes() throws SQLException {
// TODO
return 0;
}
public native int step(long stmt);
@VisibleForTesting
native void throwJavaException(int errorCode) throws SQLException;
@@ -132,42 +126,6 @@ public final class LimboDB extends AbstractDB {
*/
@NativeInvocation
private void throwLimboException(int errorCode, byte[] errorMessageBytes) throws SQLException {
String errorMessage = utf8ByteBufferToString(errorMessageBytes);
throw buildLimboException(errorCode, errorMessage);
}
/**
* Throws formatted SQLException with error code and message.
*
* @param errorCode Error code.
* @param errorMessage Error message.
*/
public LimboException buildLimboException(int errorCode, @Nullable String errorMessage) throws SQLException {
LimboErrorCode code = LimboErrorCode.getErrorCode(errorCode);
String msg;
if (code == LimboErrorCode.UNKNOWN_ERROR) {
msg = String.format("%s:%s (%s)", code, errorCode, errorMessage);
} else {
msg = String.format("%s (%s)", code, errorMessage);
}
return new LimboException(msg, code);
}
@Nullable
private static String utf8ByteBufferToString(@Nullable byte[] buffer) {
if (buffer == null) {
return null;
}
return new String(buffer, StandardCharsets.UTF_8);
}
@Nullable
private static byte[] stringToUtf8ByteArray(@Nullable String str) {
if (str == null) {
return null;
}
return str.getBytes(StandardCharsets.UTF_8);
LimboExceptionUtils.throwLimboException(errorCode, errorMessageBytes);
}
}

View File

@@ -17,25 +17,25 @@ public class LimboDBFactory {
* Otherwise, it creates a new instance and stores it in the database holder.
*
* @param url the URL of the database
* @param fileName the path to the database file
* @param filePath the path to the database file
* @param properties additional properties for the database connection
* @return an instance of {@link LimboDB}
* @throws SQLException if there is an error opening the connection
* @throws IllegalArgumentException if the fileName is empty
*/
public static LimboDB open(String url, String fileName, Properties properties) throws SQLException {
public static LimboDB open(String url, String filePath, Properties properties) throws SQLException {
if (databaseHolder.containsKey(url)) {
return databaseHolder.get(url);
}
if (fileName.isEmpty()) {
throw new IllegalArgumentException("fileName should not be empty");
if (filePath.isEmpty()) {
throw new IllegalArgumentException("filePath should not be empty");
}
final LimboDB database;
try {
LimboDB.load();
database = LimboDB.create(url, fileName);
database = LimboDB.create(url, filePath);
} catch (Exception e) {
throw new SQLException("Error opening connection", e);
}

View File

@@ -1,6 +1,6 @@
package org.github.tursodatabase.jdbc4;
import org.github.tursodatabase.LimboConnection;
import org.github.tursodatabase.core.LimboConnection;
import org.github.tursodatabase.annotations.SkipNullableCheck;
import java.sql.*;
@@ -11,8 +11,12 @@ import java.util.concurrent.Executor;
public class JDBC4Connection extends LimboConnection {
public JDBC4Connection(String url, String fileName, Properties properties) throws SQLException {
super(url, fileName, properties);
public JDBC4Connection(String url, String filePath) throws SQLException {
super(url, filePath);
}
public JDBC4Connection(String url, String filePath, Properties properties) throws SQLException {
super(url, filePath, properties);
}
@Override

View File

@@ -18,9 +18,9 @@ class JDBC4ConnectionTest {
@BeforeEach
void setUp() throws Exception {
String fileUrl = TestUtils.createTempFile();
String url = "jdbc:sqlite:" + fileUrl;
connection = new JDBC4Connection(url, fileUrl, new Properties());
String filePath = TestUtils.createTempFile();
String url = "jdbc:sqlite:" + filePath;
connection = new JDBC4Connection(url, filePath, new Properties());
}
@Test