mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-09 03:04:20 +01:00
Merge 'SDK: enable indices everywhere' from Nikita Sivukhin
Indices enabled by default in the shell - so let's enable them also in the SDK Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com> Reviewed-by: Preston Thorpe <preston@turso.tech> Closes #2581
This commit is contained in:
@@ -23,10 +23,10 @@ pub struct ConnectArgs {
|
||||
pub async fn connect(args: ConnectArgs) -> RustConnection {
|
||||
let database = if args.url == ":memory:" {
|
||||
let io: Arc<dyn turso_core::IO> = Arc::new(turso_core::MemoryIO::new());
|
||||
turso_core::Database::open_file(io, args.url.as_str(), false, false)
|
||||
turso_core::Database::open_file(io, args.url.as_str(), false, true)
|
||||
} else {
|
||||
let io: Arc<dyn turso_core::IO> = Arc::new(turso_core::PlatformIO::new().unwrap());
|
||||
turso_core::Database::open_file(io, args.url.as_str(), false, false)
|
||||
turso_core::Database::open_file(io, args.url.as_str(), false, true)
|
||||
}
|
||||
.unwrap();
|
||||
let connection = database.connect().unwrap();
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
_ "github.com/tursodatabase/turso"
|
||||
@@ -683,6 +684,53 @@ func TestParameterOrdering(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndex(t *testing.T) {
|
||||
newConn, err := sql.Open("sqlite3", ":memory:")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening new connection: %v", err)
|
||||
}
|
||||
sql := "CREATE TABLE users (name TEXT PRIMARY KEY, email TEXT)"
|
||||
_, err = newConn.Exec(sql)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating table: %v", err)
|
||||
}
|
||||
sql = "CREATE INDEX email_idx ON users(email)"
|
||||
_, err = newConn.Exec(sql)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating index: %v", err)
|
||||
}
|
||||
|
||||
// Test inserting with parameters in a different order than
|
||||
// the table definition.
|
||||
sql = "INSERT INTO users VALUES ('alice', 'a@b.c'), ('bob', 'b@d.e')"
|
||||
_, err = newConn.Exec(sql)
|
||||
if err != nil {
|
||||
t.Fatalf("Error inserting data: %v", err)
|
||||
}
|
||||
|
||||
for filter, row := range map[string][]string{
|
||||
"a@b.c": []string{"alice", "a@b.c"},
|
||||
"b@d.e": []string{"bob", "b@d.e"},
|
||||
} {
|
||||
query := "SELECT * FROM users WHERE email = ?"
|
||||
rows, err := newConn.Query(query, filter)
|
||||
if err != nil {
|
||||
t.Fatalf("Error executing query: %v", err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var name, email string
|
||||
err := rows.Scan(&name, &email)
|
||||
t.Log("name,email:", name, email)
|
||||
if err != nil {
|
||||
t.Fatal("Error scanning row: ", err)
|
||||
}
|
||||
if !slices.Equal([]string{name, email}, row) {
|
||||
t.Fatal("Unexpected result", row, []string{name, email})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func slicesAreEq(a, b []byte) bool {
|
||||
if len(a) != len(b) {
|
||||
fmt.Printf("LENGTHS NOT EQUAL: %d != %d\n", len(a), len(b))
|
||||
|
||||
@@ -20,7 +20,7 @@ pub unsafe extern "C" fn db_open(path: *const c_char) -> *mut c_void {
|
||||
}
|
||||
let path = unsafe { std::ffi::CStr::from_ptr(path) };
|
||||
let path = path.to_str().unwrap();
|
||||
let Ok((io, conn)) = Connection::from_uri(path, false, false, false) else {
|
||||
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()
|
||||
|
||||
@@ -68,7 +68,7 @@ pub extern "system" fn Java_tech_turso_core_TursoDB_openUtf8<'local>(
|
||||
}
|
||||
};
|
||||
|
||||
let db = match Database::open_file(io.clone(), &path, false, false) {
|
||||
let db = match Database::open_file(io.clone(), &path, false, true) {
|
||||
Ok(db) => db,
|
||||
Err(e) => {
|
||||
set_err_msg_and_throw_exception(&mut env, obj, TURSO_ETC, e.to_string());
|
||||
|
||||
@@ -66,7 +66,7 @@ impl Database {
|
||||
|
||||
let db_file = Arc::new(DatabaseFile::new(file));
|
||||
let db =
|
||||
turso_core::Database::open(io.clone(), &path, db_file, false, false).map_err(|e| {
|
||||
turso_core::Database::open(io.clone(), &path, db_file, false, true).map_err(|e| {
|
||||
Error::new(
|
||||
Status::GenericFailure,
|
||||
format!("Failed to open database: {e}"),
|
||||
|
||||
@@ -315,10 +315,9 @@ impl Drop for Connection {
|
||||
}
|
||||
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
#[pyfunction(signature = (path, experimental_indexes=None))]
|
||||
pub fn connect(path: &str, experimental_indexes: Option<bool>) -> Result<Connection> {
|
||||
let experimental_indexes = experimental_indexes.unwrap_or(true);
|
||||
match turso_core::Connection::from_uri(path, experimental_indexes, false, false) {
|
||||
#[pyfunction(signature = (path))]
|
||||
pub fn connect(path: &str) -> Result<Connection> {
|
||||
match turso_core::Connection::from_uri(path, true, false, false) {
|
||||
Ok((io, conn)) => Ok(Connection { conn, _io: io }),
|
||||
Err(e) => Err(PyErr::new::<ProgrammingError, _>(format!(
|
||||
"Failed to create connection: {e:?}"
|
||||
|
||||
@@ -89,6 +89,24 @@ def test_in_memory_fetchone_select_all_users(provider):
|
||||
assert alice
|
||||
assert alice == (1, "alice")
|
||||
|
||||
@pytest.mark.parametrize("provider", ["sqlite3", "turso"])
|
||||
def test_in_memory_index(provider):
|
||||
conn = connect(provider, ":memory:")
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("CREATE TABLE users (name TEXT PRIMARY KEY, email TEXT)")
|
||||
cursor.execute("CREATE INDEX email_idx ON users(email)")
|
||||
cursor.execute("INSERT INTO users VALUES ('alice', 'a@b.c'), ('bob', 'b@d.e')")
|
||||
|
||||
cursor.execute("SELECT * FROM users WHERE email = 'a@b.c'")
|
||||
alice = cursor.fetchall()
|
||||
|
||||
cursor.execute("SELECT * FROM users WHERE email = 'b@d.e'")
|
||||
bob = cursor.fetchall()
|
||||
|
||||
conn.close()
|
||||
assert alice == [("alice", "a@b.c")]
|
||||
assert bob == [("bob", "b@d.e")]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("provider", ["sqlite3", "turso"])
|
||||
def test_fetchone_select_all_users(provider):
|
||||
|
||||
@@ -108,27 +108,19 @@ impl Builder {
|
||||
io,
|
||||
self.path.as_str(),
|
||||
self.enable_mvcc,
|
||||
indexes_enabled(),
|
||||
true,
|
||||
)?;
|
||||
Ok(Database { inner: db })
|
||||
}
|
||||
path => {
|
||||
let io: Arc<dyn turso_core::IO> = Arc::new(turso_core::PlatformIO::new()?);
|
||||
let db =
|
||||
turso_core::Database::open_file(io, path, self.enable_mvcc, indexes_enabled())?;
|
||||
let db = turso_core::Database::open_file(io, path, self.enable_mvcc, true)?;
|
||||
Ok(Database { inner: db })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn indexes_enabled() -> bool {
|
||||
#[cfg(feature = "experimental_indexes")]
|
||||
return true;
|
||||
#[cfg(not(feature = "experimental_indexes"))]
|
||||
return false;
|
||||
}
|
||||
|
||||
/// A database.
|
||||
///
|
||||
/// The `Database` object points to a database and allows you to connect to it
|
||||
|
||||
@@ -297,3 +297,40 @@ async fn test_row_get_conversion_error() {
|
||||
let result: Result<u32, _> = row.get(0);
|
||||
assert!(matches!(result, Err(Error::ConversionFailure(_))));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_index() {
|
||||
let db = Builder::new_local(":memory:").build().await.unwrap();
|
||||
let conn = db.connect().unwrap();
|
||||
|
||||
conn.execute("CREATE TABLE users (name TEXT PRIMARY KEY, email TEXT)", ())
|
||||
.await
|
||||
.unwrap();
|
||||
conn.execute("CREATE INDEX email_idx ON users(email)", ())
|
||||
.await
|
||||
.unwrap();
|
||||
conn.execute(
|
||||
"INSERT INTO users VALUES ('alice', 'a@b.c'), ('bob', 'b@d.e')",
|
||||
(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut rows = conn
|
||||
.query("SELECT * FROM users WHERE email = 'a@b.c'", ())
|
||||
.await
|
||||
.unwrap();
|
||||
let row = rows.next().await.unwrap().unwrap();
|
||||
assert!(row.get::<String>(0).unwrap() == "alice");
|
||||
assert!(row.get::<String>(1).unwrap() == "a@b.c");
|
||||
assert!(rows.next().await.unwrap().is_none());
|
||||
|
||||
let mut rows = conn
|
||||
.query("SELECT * FROM users WHERE email = 'b@d.e'", ())
|
||||
.await
|
||||
.unwrap();
|
||||
let row = rows.next().await.unwrap().unwrap();
|
||||
assert!(row.get::<String>(0).unwrap() == "bob");
|
||||
assert!(row.get::<String>(1).unwrap() == "b@d.e");
|
||||
assert!(rows.next().await.unwrap().is_none());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user