mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-21 00:54:19 +01:00
Rename Go driver to turso to not conflict with sqlite3, rename limbo->turso
This commit is contained in:
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -2066,13 +2066,6 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "limbo-go"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"turso_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "limbo_completion"
|
||||
version = "0.1.4"
|
||||
@@ -3984,6 +3977,13 @@ dependencies = [
|
||||
"turso_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "turso-go"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"turso_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "turso-java"
|
||||
version = "0.1.4"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "limbo-go"
|
||||
name = "turso-go"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
@@ -8,7 +8,7 @@ repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "_limbo_go"
|
||||
name = "_turso_go"
|
||||
crate-type = ["cdylib"]
|
||||
path = "rs_src/lib.rs"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Limbo driver for Go's `database/sql` library
|
||||
# Turso driver for Go's `database/sql` library
|
||||
|
||||
**NOTE:** this is currently __heavily__ W.I.P and is not yet in a usable state.
|
||||
|
||||
@@ -17,7 +17,7 @@ To build with embedded library support, follow these steps:
|
||||
git clone https://github.com/tursodatabase/turso
|
||||
|
||||
# Navigate to the Go bindings directory
|
||||
cd limbo/bindings/go
|
||||
cd turso/bindings/go
|
||||
|
||||
# Build the library (defaults to release build)
|
||||
./build_lib.sh
|
||||
@@ -52,34 +52,34 @@ Build the driver with the embedded library as described above, then simply impor
|
||||
|
||||
#### Linux | MacOS
|
||||
|
||||
_All commands listed are relative to the bindings/go directory in the limbo repository_
|
||||
_All commands listed are relative to the bindings/go directory in the turso repository_
|
||||
|
||||
```
|
||||
cargo build --package limbo-go
|
||||
cargo build --package turso-go
|
||||
|
||||
# Your LD_LIBRARY_PATH environment variable must include limbo's `target/debug` directory
|
||||
# Your LD_LIBRARY_PATH environment variable must include turso's `target/debug` directory
|
||||
|
||||
export LD_LIBRARY_PATH="/path/to/limbo/target/debug:$LD_LIBRARY_PATH"
|
||||
export LD_LIBRARY_PATH="/path/to/turso/target/debug:$LD_LIBRARY_PATH"
|
||||
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
```
|
||||
cargo build --package limbo-go
|
||||
cargo build --package turso-go
|
||||
|
||||
# You must add limbo's `target/debug` directory to your PATH
|
||||
# You must add turso's `target/debug` directory to your PATH
|
||||
# or you could built + copy the .dll to a location in your PATH
|
||||
# or just the CWD of your go module
|
||||
|
||||
cp path\to\limbo\target\debug\lib_limbo_go.dll .
|
||||
cp path\to\turso\target\debug\lib_turso_go.dll .
|
||||
|
||||
go test
|
||||
|
||||
```
|
||||
**Temporarily** you may have to clone the limbo repository and run:
|
||||
**Temporarily** you may have to clone the turso repository and run:
|
||||
|
||||
`go mod edit -replace github.com/tursodatabase/turso=/path/to/limbo/bindings/go`
|
||||
`go mod edit -replace github.com/tursodatabase/turso=/path/to/turso/bindings/go`
|
||||
|
||||
```go
|
||||
import (
|
||||
@@ -89,19 +89,19 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := sql.Open("sqlite3", ":memory:")
|
||||
conn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
sql := "CREATE table go_limbo (foo INTEGER, bar TEXT)"
|
||||
sql := "CREATE table go_turso (foo INTEGER, bar TEXT)"
|
||||
_ = conn.Exec(sql)
|
||||
|
||||
sql = "INSERT INTO go_limbo (foo, bar) values (?, ?)"
|
||||
sql = "INSERT INTO go_turso (foo, bar) values (?, ?)"
|
||||
stmt, _ := conn.Prepare(sql)
|
||||
defer stmt.Close()
|
||||
_ = stmt.Exec(42, "limbo")
|
||||
rows, _ := conn.Query("SELECT * from go_limbo")
|
||||
_ = stmt.Exec(42, "turso")
|
||||
rows, _ := conn.Query("SELECT * from go_turso")
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var a int
|
||||
|
||||
@@ -6,12 +6,12 @@ set -e
|
||||
# Accept build type as parameter, default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
|
||||
echo "Building Limbo Go library for current platform (build type: $BUILD_TYPE)..."
|
||||
echo "Building turso Go library for current platform (build type: $BUILD_TYPE)..."
|
||||
|
||||
# Determine platform-specific details
|
||||
case "$(uname -s)" in
|
||||
Darwin*)
|
||||
OUTPUT_NAME="lib_limbo_go.dylib"
|
||||
OUTPUT_NAME="lib_turso_go.dylib"
|
||||
# Map x86_64 to amd64 for Go compatibility
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
@@ -20,7 +20,7 @@ case "$(uname -s)" in
|
||||
PLATFORM="darwin_${ARCH}"
|
||||
;;
|
||||
Linux*)
|
||||
OUTPUT_NAME="lib_limbo_go.so"
|
||||
OUTPUT_NAME="lib_turso_go.so"
|
||||
# Map x86_64 to amd64 for Go compatibility
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
@@ -29,7 +29,7 @@ case "$(uname -s)" in
|
||||
PLATFORM="linux_${ARCH}"
|
||||
;;
|
||||
MINGW*|MSYS*|CYGWIN*)
|
||||
OUTPUT_NAME="lib_limbo_go.dll"
|
||||
OUTPUT_NAME="lib_turso_go.dll"
|
||||
if [ "$(uname -m)" == "x86_64" ]; then
|
||||
PLATFORM="windows_amd64"
|
||||
else
|
||||
@@ -60,11 +60,11 @@ else
|
||||
fi
|
||||
|
||||
# Build the library
|
||||
echo "Running cargo build ${CARGO_ARGS} --package limbo-go"
|
||||
cargo build ${CARGO_ARGS} --package limbo-go
|
||||
echo "Running cargo build ${CARGO_ARGS} --package turso-go"
|
||||
cargo build ${CARGO_ARGS} --package turso-go
|
||||
|
||||
# Copy to the appropriate directory
|
||||
echo "Copying $OUTPUT_NAME to $OUTPUT_DIR/"
|
||||
cp "../../target/${TARGET_DIR}/$OUTPUT_NAME" "$OUTPUT_DIR/"
|
||||
|
||||
echo "Library built successfully for $PLATFORM ($BUILD_TYPE build)"
|
||||
echo "Library built successfully for $PLATFORM ($BUILD_TYPE build)"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -16,16 +16,16 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sql.Register(driverName, &limboDriver{})
|
||||
sql.Register(driverName, &tursoDriver{})
|
||||
}
|
||||
|
||||
type limboDriver struct {
|
||||
type tursoDriver struct {
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
libOnce sync.Once
|
||||
limboLib uintptr
|
||||
tursoLib uintptr
|
||||
loadErr error
|
||||
dbOpen func(string) uintptr
|
||||
dbClose func(uintptr) uintptr
|
||||
@@ -49,32 +49,32 @@ var (
|
||||
// Register all the symbols on library load
|
||||
func ensureLibLoaded() error {
|
||||
libOnce.Do(func() {
|
||||
limboLib, loadErr = loadLibrary()
|
||||
tursoLib, loadErr = loadLibrary()
|
||||
if loadErr != nil {
|
||||
return
|
||||
}
|
||||
purego.RegisterLibFunc(&dbOpen, limboLib, FfiDbOpen)
|
||||
purego.RegisterLibFunc(&dbClose, limboLib, FfiDbClose)
|
||||
purego.RegisterLibFunc(&connPrepare, limboLib, FfiDbPrepare)
|
||||
purego.RegisterLibFunc(&connGetError, limboLib, FfiDbGetError)
|
||||
purego.RegisterLibFunc(&freeBlobFunc, limboLib, FfiFreeBlob)
|
||||
purego.RegisterLibFunc(&freeStringFunc, limboLib, FfiFreeCString)
|
||||
purego.RegisterLibFunc(&rowsGetColumns, limboLib, FfiRowsGetColumns)
|
||||
purego.RegisterLibFunc(&rowsGetColumnName, limboLib, FfiRowsGetColumnName)
|
||||
purego.RegisterLibFunc(&rowsGetValue, limboLib, FfiRowsGetValue)
|
||||
purego.RegisterLibFunc(&closeRows, limboLib, FfiRowsClose)
|
||||
purego.RegisterLibFunc(&rowsNext, limboLib, FfiRowsNext)
|
||||
purego.RegisterLibFunc(&rowsGetError, limboLib, FfiRowsGetError)
|
||||
purego.RegisterLibFunc(&stmtQuery, limboLib, FfiStmtQuery)
|
||||
purego.RegisterLibFunc(&stmtExec, limboLib, FfiStmtExec)
|
||||
purego.RegisterLibFunc(&stmtParamCount, limboLib, FfiStmtParameterCount)
|
||||
purego.RegisterLibFunc(&stmtGetError, limboLib, FfiStmtGetError)
|
||||
purego.RegisterLibFunc(&stmtClose, limboLib, FfiStmtClose)
|
||||
purego.RegisterLibFunc(&dbOpen, tursoLib, FfiDbOpen)
|
||||
purego.RegisterLibFunc(&dbClose, tursoLib, FfiDbClose)
|
||||
purego.RegisterLibFunc(&connPrepare, tursoLib, FfiDbPrepare)
|
||||
purego.RegisterLibFunc(&connGetError, tursoLib, FfiDbGetError)
|
||||
purego.RegisterLibFunc(&freeBlobFunc, tursoLib, FfiFreeBlob)
|
||||
purego.RegisterLibFunc(&freeStringFunc, tursoLib, FfiFreeCString)
|
||||
purego.RegisterLibFunc(&rowsGetColumns, tursoLib, FfiRowsGetColumns)
|
||||
purego.RegisterLibFunc(&rowsGetColumnName, tursoLib, FfiRowsGetColumnName)
|
||||
purego.RegisterLibFunc(&rowsGetValue, tursoLib, FfiRowsGetValue)
|
||||
purego.RegisterLibFunc(&closeRows, tursoLib, FfiRowsClose)
|
||||
purego.RegisterLibFunc(&rowsNext, tursoLib, FfiRowsNext)
|
||||
purego.RegisterLibFunc(&rowsGetError, tursoLib, FfiRowsGetError)
|
||||
purego.RegisterLibFunc(&stmtQuery, tursoLib, FfiStmtQuery)
|
||||
purego.RegisterLibFunc(&stmtExec, tursoLib, FfiStmtExec)
|
||||
purego.RegisterLibFunc(&stmtParamCount, tursoLib, FfiStmtParameterCount)
|
||||
purego.RegisterLibFunc(&stmtGetError, tursoLib, FfiStmtGetError)
|
||||
purego.RegisterLibFunc(&stmtClose, tursoLib, FfiStmtClose)
|
||||
})
|
||||
return loadErr
|
||||
}
|
||||
|
||||
func (d *limboDriver) Open(name string) (driver.Conn, error) {
|
||||
func (d *tursoDriver) Open(name string) (driver.Conn, error) {
|
||||
d.Lock()
|
||||
conn, err := openConn(name)
|
||||
d.Unlock()
|
||||
@@ -84,23 +84,23 @@ func (d *limboDriver) Open(name string) (driver.Conn, error) {
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
type limboConn struct {
|
||||
type tursoConn struct {
|
||||
sync.Mutex
|
||||
ctx uintptr
|
||||
}
|
||||
|
||||
func openConn(dsn string) (*limboConn, error) {
|
||||
func openConn(dsn string) (*tursoConn, error) {
|
||||
ctx := dbOpen(dsn)
|
||||
if ctx == 0 {
|
||||
return nil, fmt.Errorf("failed to open database for dsn=%q", dsn)
|
||||
}
|
||||
return &limboConn{
|
||||
return &tursoConn{
|
||||
sync.Mutex{},
|
||||
ctx,
|
||||
}, loadErr
|
||||
}
|
||||
|
||||
func (c *limboConn) Close() error {
|
||||
func (c *tursoConn) Close() error {
|
||||
if c.ctx == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func (c *limboConn) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *limboConn) getError() error {
|
||||
func (c *tursoConn) getError() error {
|
||||
if c.ctx == 0 {
|
||||
return errors.New("connection closed")
|
||||
}
|
||||
@@ -124,7 +124,7 @@ func (c *limboConn) getError() error {
|
||||
return errors.New(cpy)
|
||||
}
|
||||
|
||||
func (c *limboConn) Prepare(query string) (driver.Stmt, error) {
|
||||
func (c *tursoConn) Prepare(query string) (driver.Stmt, error) {
|
||||
if c.ctx == 0 {
|
||||
return nil, errors.New("connection closed")
|
||||
}
|
||||
@@ -137,13 +137,13 @@ func (c *limboConn) Prepare(query string) (driver.Stmt, error) {
|
||||
return newStmt(stmtPtr, query), nil
|
||||
}
|
||||
|
||||
// limboTx implements driver.Tx
|
||||
type limboTx struct {
|
||||
conn *limboConn
|
||||
// tursoTx implements driver.Tx
|
||||
type tursoTx struct {
|
||||
conn *tursoConn
|
||||
}
|
||||
|
||||
// Begin starts a new transaction with default isolation level
|
||||
func (c *limboConn) Begin() (driver.Tx, error) {
|
||||
func (c *tursoConn) Begin() (driver.Tx, error) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
@@ -165,12 +165,12 @@ func (c *limboConn) Begin() (driver.Tx, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &limboTx{conn: c}, nil
|
||||
return &tursoTx{conn: c}, nil
|
||||
}
|
||||
|
||||
// BeginTx starts a transaction with the specified options.
|
||||
// Currently only supports default isolation level and non-read-only transactions.
|
||||
func (c *limboConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||
func (c *tursoConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||
// Skip handling non-default isolation levels and read-only mode
|
||||
// for now, letting database/sql package handle these cases
|
||||
if opts.Isolation != driver.IsolationLevel(sql.LevelDefault) || opts.ReadOnly {
|
||||
@@ -187,7 +187,7 @@ func (c *limboConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.
|
||||
}
|
||||
|
||||
// Commit commits the transaction
|
||||
func (tx *limboTx) Commit() error {
|
||||
func (tx *tursoTx) Commit() error {
|
||||
tx.conn.Lock()
|
||||
defer tx.conn.Unlock()
|
||||
|
||||
@@ -208,8 +208,7 @@ func (tx *limboTx) Commit() error {
|
||||
}
|
||||
|
||||
// Rollback aborts the transaction.
|
||||
// Note: This operation is not currently fully supported by Limbo and will return an error.
|
||||
func (tx *limboTx) Rollback() error {
|
||||
func (tx *tursoTx) Rollback() error {
|
||||
tx.conn.Lock()
|
||||
defer tx.conn.Unlock()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Go bindings for the Limbo database.
|
||||
// Go bindings for the turso database.
|
||||
//
|
||||
// This file implements library embedding and extraction at runtime, a pattern
|
||||
// also used in several other Go projects that need to distribute native binaries:
|
||||
@@ -21,7 +21,7 @@
|
||||
// The embedded library is extracted to a user-specific temporary directory and
|
||||
// loaded dynamically. If extraction fails, the code falls back to the traditional
|
||||
// method of searching system paths.
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"embed"
|
||||
@@ -52,11 +52,11 @@ func extractEmbeddedLibrary() (string, error) {
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
libName = "lib_limbo_go.dylib"
|
||||
libName = "lib_turso_go.dylib"
|
||||
case "linux":
|
||||
libName = "lib_limbo_go.so"
|
||||
libName = "lib_turso_go.so"
|
||||
case "windows":
|
||||
libName = "lib_limbo_go.dll"
|
||||
libName = "lib_turso_go.dll"
|
||||
default:
|
||||
extractErr = fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
return
|
||||
@@ -80,7 +80,7 @@ func extractEmbeddedLibrary() (string, error) {
|
||||
platformDir = fmt.Sprintf("%s_%s", runtime.GOOS, archSuffix)
|
||||
|
||||
// Create a unique temporary directory for the current user
|
||||
tempDir := filepath.Join(os.TempDir(), fmt.Sprintf("limbo-go-%d", os.Getuid()))
|
||||
tempDir := filepath.Join(os.TempDir(), fmt.Sprintf("turso-go-%d", os.Getuid()))
|
||||
if err := os.MkdirAll(tempDir, 0755); err != nil {
|
||||
extractErr = fmt.Errorf("failed to create temp directory: %w", err)
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type limboRows struct {
|
||||
type tursoRows struct {
|
||||
mu sync.Mutex
|
||||
ctx uintptr
|
||||
columns []string
|
||||
@@ -16,8 +16,8 @@ type limboRows struct {
|
||||
closed bool
|
||||
}
|
||||
|
||||
func newRows(ctx uintptr) *limboRows {
|
||||
return &limboRows{
|
||||
func newRows(ctx uintptr) *tursoRows {
|
||||
return &tursoRows{
|
||||
mu: sync.Mutex{},
|
||||
ctx: ctx,
|
||||
columns: nil,
|
||||
@@ -26,14 +26,14 @@ func newRows(ctx uintptr) *limboRows {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *limboRows) isClosed() bool {
|
||||
func (r *tursoRows) isClosed() bool {
|
||||
if r.ctx == 0 || r.closed {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *limboRows) Columns() []string {
|
||||
func (r *tursoRows) Columns() []string {
|
||||
if r.isClosed() {
|
||||
return nil
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func (r *limboRows) Columns() []string {
|
||||
return r.columns
|
||||
}
|
||||
|
||||
func (r *limboRows) Close() error {
|
||||
func (r *tursoRows) Close() error {
|
||||
r.err = errors.New(RowsClosedErr)
|
||||
if r.isClosed() {
|
||||
return r.err
|
||||
@@ -67,7 +67,7 @@ func (r *limboRows) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *limboRows) Err() error {
|
||||
func (r *tursoRows) Err() error {
|
||||
if r.err == nil {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
@@ -76,7 +76,7 @@ func (r *limboRows) Err() error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
func (r *limboRows) Next(dest []driver.Value) error {
|
||||
func (r *tursoRows) Next(dest []driver.Value) error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if r.isClosed() {
|
||||
@@ -106,7 +106,7 @@ func (r *limboRows) Next(dest []driver.Value) error {
|
||||
}
|
||||
|
||||
// mutex will already be locked. this is always called after FFI
|
||||
func (r *limboRows) getError() error {
|
||||
func (r *tursoRows) getError() error {
|
||||
if r.isClosed() {
|
||||
return r.err
|
||||
}
|
||||
|
||||
@@ -23,19 +23,19 @@ pub unsafe extern "C" fn db_open(path: *const c_char) -> *mut c_void {
|
||||
let Ok((io, conn)) = Connection::from_uri(path, true, false, false) else {
|
||||
panic!("Failed to open connection with path: {path}");
|
||||
};
|
||||
LimboConn::new(conn, io).to_ptr()
|
||||
TursoConn::new(conn, io).to_ptr()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct LimboConn {
|
||||
struct TursoConn {
|
||||
conn: Arc<Connection>,
|
||||
io: Arc<dyn turso_core::IO>,
|
||||
err: Option<LimboError>,
|
||||
}
|
||||
|
||||
impl LimboConn {
|
||||
impl TursoConn {
|
||||
fn new(conn: Arc<Connection>, io: Arc<dyn turso_core::IO>) -> Self {
|
||||
LimboConn {
|
||||
TursoConn {
|
||||
conn,
|
||||
io,
|
||||
err: None,
|
||||
@@ -47,11 +47,11 @@ impl LimboConn {
|
||||
Box::into_raw(Box::new(self)) as *mut c_void
|
||||
}
|
||||
|
||||
fn from_ptr(ptr: *mut c_void) -> &'static mut LimboConn {
|
||||
fn from_ptr(ptr: *mut c_void) -> &'static mut TursoConn {
|
||||
if ptr.is_null() {
|
||||
panic!("Null pointer");
|
||||
}
|
||||
unsafe { &mut *(ptr as *mut LimboConn) }
|
||||
unsafe { &mut *(ptr as *mut TursoConn) }
|
||||
}
|
||||
|
||||
fn get_error(&mut self) -> *const c_char {
|
||||
@@ -73,7 +73,7 @@ pub extern "C" fn db_get_error(ctx: *mut c_void) -> *const c_char {
|
||||
if ctx.is_null() {
|
||||
return std::ptr::null();
|
||||
}
|
||||
let conn = LimboConn::from_ptr(ctx);
|
||||
let conn = TursoConn::from_ptr(ctx);
|
||||
conn.get_error()
|
||||
}
|
||||
|
||||
@@ -83,6 +83,6 @@ pub extern "C" fn db_get_error(ctx: *mut c_void) -> *const c_char {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn db_close(db: *mut c_void) {
|
||||
if !db.is_null() {
|
||||
let _ = unsafe { Box::from_raw(db as *mut LimboConn) };
|
||||
let _ = unsafe { Box::from_raw(db as *mut TursoConn) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
use crate::{
|
||||
types::{LimboValue, ResultCode},
|
||||
LimboConn,
|
||||
types::{ResultCode, TursoValue},
|
||||
TursoConn,
|
||||
};
|
||||
use std::ffi::{c_char, c_void};
|
||||
use turso_core::{LimboError, Statement, StepResult, Value};
|
||||
|
||||
pub struct LimboRows<'conn> {
|
||||
pub struct TursoRows<'conn> {
|
||||
stmt: Box<Statement>,
|
||||
_conn: &'conn mut LimboConn,
|
||||
_conn: &'conn mut TursoConn,
|
||||
err: Option<LimboError>,
|
||||
}
|
||||
|
||||
impl<'conn> LimboRows<'conn> {
|
||||
pub fn new(stmt: Statement, conn: &'conn mut LimboConn) -> Self {
|
||||
LimboRows {
|
||||
impl<'conn> TursoRows<'conn> {
|
||||
pub fn new(stmt: Statement, conn: &'conn mut TursoConn) -> Self {
|
||||
TursoRows {
|
||||
stmt: Box::new(stmt),
|
||||
_conn: conn,
|
||||
err: None,
|
||||
@@ -25,11 +25,11 @@ impl<'conn> LimboRows<'conn> {
|
||||
Box::into_raw(Box::new(self)) as *mut c_void
|
||||
}
|
||||
|
||||
pub fn from_ptr(ptr: *mut c_void) -> &'conn mut LimboRows<'conn> {
|
||||
pub fn from_ptr(ptr: *mut c_void) -> &'conn mut TursoRows<'conn> {
|
||||
if ptr.is_null() {
|
||||
panic!("Null pointer");
|
||||
}
|
||||
unsafe { &mut *(ptr as *mut LimboRows) }
|
||||
unsafe { &mut *(ptr as *mut TursoRows) }
|
||||
}
|
||||
|
||||
fn get_error(&mut self) -> *const c_char {
|
||||
@@ -49,7 +49,7 @@ pub extern "C" fn rows_next(ctx: *mut c_void) -> ResultCode {
|
||||
if ctx.is_null() {
|
||||
return ResultCode::Error;
|
||||
}
|
||||
let ctx = LimboRows::from_ptr(ctx);
|
||||
let ctx = TursoRows::from_ptr(ctx);
|
||||
|
||||
match ctx.stmt.step() {
|
||||
Ok(StepResult::Row) => ResultCode::Row,
|
||||
@@ -76,11 +76,11 @@ pub extern "C" fn rows_get_value(ctx: *mut c_void, col_idx: usize) -> *const c_v
|
||||
if ctx.is_null() {
|
||||
return std::ptr::null();
|
||||
}
|
||||
let ctx = LimboRows::from_ptr(ctx);
|
||||
let ctx = TursoRows::from_ptr(ctx);
|
||||
|
||||
if let Some(row) = ctx.stmt.row() {
|
||||
if let Ok(value) = row.get::<&Value>(col_idx) {
|
||||
return LimboValue::from_db_value(value).to_ptr();
|
||||
return TursoValue::from_db_value(value).to_ptr();
|
||||
}
|
||||
}
|
||||
std::ptr::null()
|
||||
@@ -101,7 +101,7 @@ pub extern "C" fn rows_get_columns(rows_ptr: *mut c_void) -> i32 {
|
||||
if rows_ptr.is_null() {
|
||||
return -1;
|
||||
}
|
||||
let rows = LimboRows::from_ptr(rows_ptr);
|
||||
let rows = TursoRows::from_ptr(rows_ptr);
|
||||
rows.stmt.num_columns() as i32
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ pub extern "C" fn rows_get_column_name(rows_ptr: *mut c_void, idx: i32) -> *cons
|
||||
if rows_ptr.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
let rows = LimboRows::from_ptr(rows_ptr);
|
||||
let rows = TursoRows::from_ptr(rows_ptr);
|
||||
if idx < 0 || idx as usize >= rows.stmt.num_columns() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
@@ -127,18 +127,18 @@ pub extern "C" fn rows_get_error(ctx: *mut c_void) -> *const c_char {
|
||||
if ctx.is_null() {
|
||||
return std::ptr::null();
|
||||
}
|
||||
let ctx = LimboRows::from_ptr(ctx);
|
||||
let ctx = TursoRows::from_ptr(ctx);
|
||||
ctx.get_error()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rows_close(ctx: *mut c_void) {
|
||||
if !ctx.is_null() {
|
||||
let rows = LimboRows::from_ptr(ctx);
|
||||
let rows = TursoRows::from_ptr(ctx);
|
||||
rows.stmt.reset();
|
||||
rows.err = None;
|
||||
}
|
||||
unsafe {
|
||||
let _ = Box::from_raw(ctx.cast::<LimboRows>());
|
||||
let _ = Box::from_raw(ctx.cast::<TursoRows>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::rows::LimboRows;
|
||||
use crate::types::{AllocPool, LimboValue, ResultCode};
|
||||
use crate::LimboConn;
|
||||
use crate::rows::TursoRows;
|
||||
use crate::types::{AllocPool, ResultCode, TursoValue};
|
||||
use crate::TursoConn;
|
||||
use std::ffi::{c_char, c_void};
|
||||
use std::num::NonZero;
|
||||
use turso_core::{LimboError, Statement, StepResult};
|
||||
@@ -12,10 +12,10 @@ pub extern "C" fn db_prepare(ctx: *mut c_void, query: *const c_char) -> *mut c_v
|
||||
}
|
||||
let query_str = unsafe { std::ffi::CStr::from_ptr(query) }.to_str().unwrap();
|
||||
|
||||
let db = LimboConn::from_ptr(ctx);
|
||||
let db = TursoConn::from_ptr(ctx);
|
||||
let stmt = db.conn.prepare(query_str);
|
||||
match stmt {
|
||||
Ok(stmt) => LimboStatement::new(Some(stmt), db).to_ptr(),
|
||||
Ok(stmt) => TursoStatement::new(Some(stmt), db).to_ptr(),
|
||||
Err(err) => {
|
||||
db.err = Some(err);
|
||||
std::ptr::null_mut()
|
||||
@@ -26,14 +26,14 @@ pub extern "C" fn db_prepare(ctx: *mut c_void, query: *const c_char) -> *mut c_v
|
||||
#[no_mangle]
|
||||
pub extern "C" fn stmt_execute(
|
||||
ctx: *mut c_void,
|
||||
args_ptr: *mut LimboValue,
|
||||
args_ptr: *mut TursoValue,
|
||||
arg_count: usize,
|
||||
changes: *mut i64,
|
||||
) -> ResultCode {
|
||||
if ctx.is_null() {
|
||||
return ResultCode::Error;
|
||||
}
|
||||
let stmt = LimboStatement::from_ptr(ctx);
|
||||
let stmt = TursoStatement::from_ptr(ctx);
|
||||
|
||||
let args = if !args_ptr.is_null() && arg_count > 0 {
|
||||
unsafe { std::slice::from_raw_parts(args_ptr, arg_count) }
|
||||
@@ -88,7 +88,7 @@ pub extern "C" fn stmt_parameter_count(ctx: *mut c_void) -> i32 {
|
||||
if ctx.is_null() {
|
||||
return -1;
|
||||
}
|
||||
let stmt = LimboStatement::from_ptr(ctx);
|
||||
let stmt = TursoStatement::from_ptr(ctx);
|
||||
let Some(statement) = stmt.statement.as_ref() else {
|
||||
stmt.err = Some(LimboError::InternalError("Statement is closed".to_string()));
|
||||
return -1;
|
||||
@@ -99,13 +99,13 @@ pub extern "C" fn stmt_parameter_count(ctx: *mut c_void) -> i32 {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn stmt_query(
|
||||
ctx: *mut c_void,
|
||||
args_ptr: *mut LimboValue,
|
||||
args_ptr: *mut TursoValue,
|
||||
args_count: usize,
|
||||
) -> *mut c_void {
|
||||
if ctx.is_null() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
let stmt = LimboStatement::from_ptr(ctx);
|
||||
let stmt = TursoStatement::from_ptr(ctx);
|
||||
let args = if !args_ptr.is_null() && args_count > 0 {
|
||||
unsafe { std::slice::from_raw_parts(args_ptr, args_count) }
|
||||
} else {
|
||||
@@ -119,21 +119,21 @@ pub extern "C" fn stmt_query(
|
||||
let val = arg.to_value(&mut pool);
|
||||
statement.bind_at(NonZero::new(i + 1).unwrap(), val);
|
||||
}
|
||||
// ownership of the statement is transferred to the LimboRows object.
|
||||
LimboRows::new(statement, stmt.conn).to_ptr()
|
||||
// ownership of the statement is transferred to the TursoRows object.
|
||||
TursoRows::new(statement, stmt.conn).to_ptr()
|
||||
}
|
||||
|
||||
pub struct LimboStatement<'conn> {
|
||||
/// If 'query' is ran on the statement, ownership is transferred to the LimboRows object
|
||||
pub struct TursoStatement<'conn> {
|
||||
/// If 'query' is ran on the statement, ownership is transferred to the TursoRows object
|
||||
pub statement: Option<Statement>,
|
||||
pub conn: &'conn mut LimboConn,
|
||||
pub conn: &'conn mut TursoConn,
|
||||
pub err: Option<LimboError>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn stmt_close(ctx: *mut c_void) -> ResultCode {
|
||||
if !ctx.is_null() {
|
||||
let stmt = unsafe { Box::from_raw(ctx as *mut LimboStatement) };
|
||||
let stmt = unsafe { Box::from_raw(ctx as *mut TursoStatement) };
|
||||
drop(stmt);
|
||||
return ResultCode::Ok;
|
||||
}
|
||||
@@ -145,13 +145,13 @@ pub extern "C" fn stmt_get_error(ctx: *mut c_void) -> *const c_char {
|
||||
if ctx.is_null() {
|
||||
return std::ptr::null();
|
||||
}
|
||||
let stmt = LimboStatement::from_ptr(ctx);
|
||||
let stmt = TursoStatement::from_ptr(ctx);
|
||||
stmt.get_error()
|
||||
}
|
||||
|
||||
impl<'conn> LimboStatement<'conn> {
|
||||
pub fn new(statement: Option<Statement>, conn: &'conn mut LimboConn) -> Self {
|
||||
LimboStatement {
|
||||
impl<'conn> TursoStatement<'conn> {
|
||||
pub fn new(statement: Option<Statement>, conn: &'conn mut TursoConn) -> Self {
|
||||
TursoStatement {
|
||||
statement,
|
||||
conn,
|
||||
err: None,
|
||||
@@ -163,11 +163,11 @@ impl<'conn> LimboStatement<'conn> {
|
||||
Box::into_raw(Box::new(self)) as *mut c_void
|
||||
}
|
||||
|
||||
fn from_ptr(ptr: *mut c_void) -> &'conn mut LimboStatement<'conn> {
|
||||
fn from_ptr(ptr: *mut c_void) -> &'conn mut TursoStatement<'conn> {
|
||||
if ptr.is_null() {
|
||||
panic!("Null pointer");
|
||||
}
|
||||
unsafe { &mut *(ptr as *mut LimboStatement) }
|
||||
unsafe { &mut *(ptr as *mut TursoStatement) }
|
||||
}
|
||||
|
||||
fn get_error(&mut self) -> *const c_char {
|
||||
|
||||
@@ -34,33 +34,33 @@ pub enum ValueType {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct LimboValue {
|
||||
pub struct TursoValue {
|
||||
value_type: ValueType,
|
||||
value: ValueUnion,
|
||||
}
|
||||
impl Debug for LimboValue {
|
||||
impl Debug for TursoValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self.value_type {
|
||||
ValueType::Integer => {
|
||||
let i = self.value.to_int();
|
||||
f.debug_struct("LimboValue").field("value", &i).finish()
|
||||
f.debug_struct("TursoValue").field("value", &i).finish()
|
||||
}
|
||||
ValueType::Real => {
|
||||
let r = self.value.to_real();
|
||||
f.debug_struct("LimboValue").field("value", &r).finish()
|
||||
f.debug_struct("TursoValue").field("value", &r).finish()
|
||||
}
|
||||
ValueType::Text => {
|
||||
let t = self.value.to_str();
|
||||
f.debug_struct("LimboValue").field("value", &t).finish()
|
||||
f.debug_struct("TursoValue").field("value", &t).finish()
|
||||
}
|
||||
ValueType::Blob => {
|
||||
let blob = self.value.to_bytes();
|
||||
f.debug_struct("LimboValue")
|
||||
f.debug_struct("TursoValue")
|
||||
.field("value", &blob.to_vec())
|
||||
.finish()
|
||||
}
|
||||
ValueType::Null => f
|
||||
.debug_struct("LimboValue")
|
||||
.debug_struct("TursoValue")
|
||||
.field("value", &"NULL")
|
||||
.finish(),
|
||||
}
|
||||
@@ -164,9 +164,9 @@ impl ValueUnion {
|
||||
}
|
||||
}
|
||||
|
||||
impl LimboValue {
|
||||
impl TursoValue {
|
||||
fn new(value_type: ValueType, value: ValueUnion) -> Self {
|
||||
LimboValue { value_type, value }
|
||||
TursoValue { value_type, value }
|
||||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
@@ -177,18 +177,18 @@ impl LimboValue {
|
||||
pub fn from_db_value(value: &turso_core::Value) -> Self {
|
||||
match value {
|
||||
turso_core::Value::Integer(i) => {
|
||||
LimboValue::new(ValueType::Integer, ValueUnion::from_int(*i))
|
||||
TursoValue::new(ValueType::Integer, ValueUnion::from_int(*i))
|
||||
}
|
||||
turso_core::Value::Float(r) => {
|
||||
LimboValue::new(ValueType::Real, ValueUnion::from_real(*r))
|
||||
TursoValue::new(ValueType::Real, ValueUnion::from_real(*r))
|
||||
}
|
||||
turso_core::Value::Text(s) => {
|
||||
LimboValue::new(ValueType::Text, ValueUnion::from_str(s.as_str()))
|
||||
TursoValue::new(ValueType::Text, ValueUnion::from_str(s.as_str()))
|
||||
}
|
||||
turso_core::Value::Blob(b) => {
|
||||
LimboValue::new(ValueType::Blob, ValueUnion::from_bytes(b.as_slice()))
|
||||
TursoValue::new(ValueType::Blob, ValueUnion::from_bytes(b.as_slice()))
|
||||
}
|
||||
turso_core::Value::Null => LimboValue::new(ValueType::Null, ValueUnion::from_null()),
|
||||
turso_core::Value::Null => TursoValue::new(ValueType::Null, ValueUnion::from_null()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -9,22 +9,22 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type limboStmt struct {
|
||||
type tursoStmt struct {
|
||||
mu sync.Mutex
|
||||
ctx uintptr
|
||||
sql string
|
||||
err error
|
||||
}
|
||||
|
||||
func newStmt(ctx uintptr, sql string) *limboStmt {
|
||||
return &limboStmt{
|
||||
func newStmt(ctx uintptr, sql string) *tursoStmt {
|
||||
return &tursoStmt{
|
||||
ctx: uintptr(ctx),
|
||||
sql: sql,
|
||||
err: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (ls *limboStmt) NumInput() int {
|
||||
func (ls *tursoStmt) NumInput() int {
|
||||
ls.mu.Lock()
|
||||
defer ls.mu.Unlock()
|
||||
res := int(stmtParamCount(ls.ctx))
|
||||
@@ -35,7 +35,7 @@ func (ls *limboStmt) NumInput() int {
|
||||
return res
|
||||
}
|
||||
|
||||
func (ls *limboStmt) Close() error {
|
||||
func (ls *tursoStmt) Close() error {
|
||||
ls.mu.Lock()
|
||||
defer ls.mu.Unlock()
|
||||
if ls.ctx == 0 {
|
||||
@@ -49,7 +49,7 @@ func (ls *limboStmt) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ls *limboStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
func (ls *tursoStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
argArray, cleanup, err := buildArgs(args)
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
@@ -80,7 +80,7 @@ func (ls *limboStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (ls *limboStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
func (ls *tursoStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
queryArgs, cleanup, err := buildArgs(args)
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
@@ -99,7 +99,7 @@ func (ls *limboStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
return newRows(rowsPtr), nil
|
||||
}
|
||||
|
||||
func (ls *limboStmt) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
|
||||
func (ls *tursoStmt) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
|
||||
stripped := namedValueToValue(args)
|
||||
argArray, cleanup, err := getArgsPtr(stripped)
|
||||
defer cleanup()
|
||||
@@ -129,7 +129,7 @@ func (ls *limboStmt) ExecContext(ctx context.Context, query string, args []drive
|
||||
}
|
||||
}
|
||||
|
||||
func (ls *limboStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
||||
func (ls *tursoStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
||||
queryArgs, allocs, err := buildNamedArgs(args)
|
||||
defer allocs()
|
||||
if err != nil {
|
||||
@@ -154,7 +154,7 @@ func (ls *limboStmt) QueryContext(ctx context.Context, args []driver.NamedValue)
|
||||
}
|
||||
}
|
||||
|
||||
func (ls *limboStmt) Err() error {
|
||||
func (ls *tursoStmt) Err() error {
|
||||
if ls.err == nil {
|
||||
ls.mu.Lock()
|
||||
defer ls.mu.Unlock()
|
||||
@@ -164,7 +164,7 @@ func (ls *limboStmt) Err() error {
|
||||
}
|
||||
|
||||
// mutex should always be locked when calling - always called after FFI
|
||||
func (ls *limboStmt) getError() error {
|
||||
func (ls *tursoStmt) getError() error {
|
||||
err := stmtGetError(ls.ctx)
|
||||
if err == 0 {
|
||||
return nil
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package limbo_test
|
||||
package turso_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
@@ -17,7 +17,7 @@ var (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
conn, connErr = sql.Open("sqlite3", ":memory:")
|
||||
conn, connErr = sql.Open("turso", ":memory:")
|
||||
if connErr != nil {
|
||||
panic(connErr)
|
||||
}
|
||||
@@ -146,7 +146,7 @@ func TestFunctions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDuplicateConnection(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
newConn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
@@ -177,7 +177,7 @@ func TestDuplicateConnection(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDuplicateConnection2(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
newConn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func TestDuplicateConnection2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConnectionError(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
newConn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
@@ -228,7 +228,7 @@ func TestConnectionError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStatementError(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
newConn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func TestStatementError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDriverRowsErrorMessages(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open database: %v", err)
|
||||
}
|
||||
@@ -285,7 +285,7 @@ func TestDriverRowsErrorMessages(t *testing.T) {
|
||||
|
||||
func TestTransaction(t *testing.T) {
|
||||
// Open database connection
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening database: %v", err)
|
||||
}
|
||||
@@ -359,7 +359,7 @@ func TestTransaction(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVectorOperations(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening connection: %v", err)
|
||||
}
|
||||
@@ -397,7 +397,7 @@ func TestVectorOperations(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSQLFeatures(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening connection: %v", err)
|
||||
}
|
||||
@@ -501,7 +501,7 @@ func TestSQLFeatures(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDateTimeFunctions(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening connection: %v", err)
|
||||
}
|
||||
@@ -536,7 +536,7 @@ func TestDateTimeFunctions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMathFunctions(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening connection: %v", err)
|
||||
}
|
||||
@@ -572,7 +572,7 @@ func TestMathFunctions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONFunctions(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
db, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening connection: %v", err)
|
||||
}
|
||||
@@ -610,7 +610,7 @@ func TestJSONFunctions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParameterOrdering(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
newConn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
@@ -685,7 +685,7 @@ func TestParameterOrdering(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIndex(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
newConn, err := sql.Open("turso", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build linux || darwin
|
||||
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build windows
|
||||
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package limbo
|
||||
package turso
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
@@ -66,8 +66,8 @@ func (rc ResultCode) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
driverName = "sqlite3"
|
||||
libName = "lib_limbo_go"
|
||||
driverName = "turso"
|
||||
libName = "lib_turso_go"
|
||||
RowsClosedErr = "sql: Rows closed"
|
||||
FfiDbOpen = "db_open"
|
||||
FfiDbClose = "db_close"
|
||||
@@ -98,7 +98,7 @@ func namedValueToValue(named []driver.NamedValue) []driver.Value {
|
||||
return out
|
||||
}
|
||||
|
||||
func buildNamedArgs(named []driver.NamedValue) ([]limboValue, func(), error) {
|
||||
func buildNamedArgs(named []driver.NamedValue) ([]tursoValue, func(), error) {
|
||||
args := namedValueToValue(named)
|
||||
return buildArgs(args)
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func (vt valueType) String() string {
|
||||
}
|
||||
|
||||
// struct to pass Go values over FFI
|
||||
type limboValue struct {
|
||||
type tursoValue struct {
|
||||
Type valueType
|
||||
_ [4]byte
|
||||
Value [8]byte
|
||||
@@ -143,12 +143,12 @@ type Blob struct {
|
||||
Len int64
|
||||
}
|
||||
|
||||
// convert a limboValue to a native Go value
|
||||
// convert a tursoValue to a native Go value
|
||||
func toGoValue(valPtr uintptr) interface{} {
|
||||
if valPtr == 0 {
|
||||
return nil
|
||||
}
|
||||
val := (*limboValue)(unsafe.Pointer(valPtr))
|
||||
val := (*tursoValue)(unsafe.Pointer(valPtr))
|
||||
switch val.Type {
|
||||
case intVal:
|
||||
return *(*int64)(unsafe.Pointer(&val.Value))
|
||||
@@ -228,50 +228,50 @@ func freeCString(cstrPtr uintptr) {
|
||||
freeStringFunc(cstrPtr)
|
||||
}
|
||||
|
||||
// convert a Go slice of driver.Value to a slice of limboValue that can be sent over FFI
|
||||
// convert a Go slice of driver.Value to a slice of tursoValue that can be sent over FFI
|
||||
// for Blob types, we have to pin them so they are not garbage collected before they can be copied
|
||||
// into a buffer on the Rust side, so we return a function to unpin them that can be deferred after this call
|
||||
func buildArgs(args []driver.Value) ([]limboValue, func(), error) {
|
||||
func buildArgs(args []driver.Value) ([]tursoValue, func(), error) {
|
||||
pinner := new(runtime.Pinner)
|
||||
argSlice := make([]limboValue, len(args))
|
||||
argSlice := make([]tursoValue, len(args))
|
||||
for i, v := range args {
|
||||
limboVal := limboValue{}
|
||||
tursoVal := tursoValue{}
|
||||
switch val := v.(type) {
|
||||
case nil:
|
||||
limboVal.Type = nullVal
|
||||
tursoVal.Type = nullVal
|
||||
case int64:
|
||||
limboVal.Type = intVal
|
||||
limboVal.Value = *(*[8]byte)(unsafe.Pointer(&val))
|
||||
tursoVal.Type = intVal
|
||||
tursoVal.Value = *(*[8]byte)(unsafe.Pointer(&val))
|
||||
case float64:
|
||||
limboVal.Type = realVal
|
||||
limboVal.Value = *(*[8]byte)(unsafe.Pointer(&val))
|
||||
tursoVal.Type = realVal
|
||||
tursoVal.Value = *(*[8]byte)(unsafe.Pointer(&val))
|
||||
case bool:
|
||||
limboVal.Type = intVal
|
||||
tursoVal.Type = intVal
|
||||
boolAsInt := int64(0)
|
||||
if val {
|
||||
boolAsInt = 1
|
||||
}
|
||||
limboVal.Value = *(*[8]byte)(unsafe.Pointer(&boolAsInt))
|
||||
tursoVal.Value = *(*[8]byte)(unsafe.Pointer(&boolAsInt))
|
||||
case string:
|
||||
limboVal.Type = textVal
|
||||
tursoVal.Type = textVal
|
||||
cstr := CString(val)
|
||||
pinner.Pin(cstr)
|
||||
*(*uintptr)(unsafe.Pointer(&limboVal.Value)) = uintptr(unsafe.Pointer(cstr))
|
||||
*(*uintptr)(unsafe.Pointer(&tursoVal.Value)) = uintptr(unsafe.Pointer(cstr))
|
||||
case []byte:
|
||||
limboVal.Type = blobVal
|
||||
tursoVal.Type = blobVal
|
||||
blob := makeBlob(val)
|
||||
pinner.Pin(blob)
|
||||
*(*uintptr)(unsafe.Pointer(&limboVal.Value)) = uintptr(unsafe.Pointer(blob))
|
||||
*(*uintptr)(unsafe.Pointer(&tursoVal.Value)) = uintptr(unsafe.Pointer(blob))
|
||||
case time.Time:
|
||||
limboVal.Type = textVal
|
||||
tursoVal.Type = textVal
|
||||
timeStr := val.Format(time.RFC3339)
|
||||
cstr := CString(timeStr)
|
||||
pinner.Pin(cstr)
|
||||
*(*uintptr)(unsafe.Pointer(&limboVal.Value)) = uintptr(unsafe.Pointer(cstr))
|
||||
*(*uintptr)(unsafe.Pointer(&tursoVal.Value)) = uintptr(unsafe.Pointer(cstr))
|
||||
default:
|
||||
return nil, pinner.Unpin, fmt.Errorf("unsupported type: %T", v)
|
||||
}
|
||||
argSlice[i] = limboVal
|
||||
argSlice[i] = tursoVal
|
||||
}
|
||||
return argSlice, pinner.Unpin, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user