Skip to content

Commit 1054c4e

Browse files
authored
Merge pull request #148 from tursodatabase/offline-writes
Offline writes
2 parents f941c5d + 2cd3ebb commit 1054c4e

File tree

10 files changed

+796
-65
lines changed

10 files changed

+796
-65
lines changed

Cargo.lock

Lines changed: 717 additions & 45 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ crate-type = ["cdylib"]
1212

1313
[dependencies]
1414
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
15-
libsql = { git = "https://github.com/tursodatabase/libsql/", rev = "20147731c4a9d6e942b159f183215e9399fda2c3", features = ["encryption"] }
15+
libsql = { git = "https://github.com/tursodatabase/libsql/", rev = "18f444290d9f2542d6da14e559d2b3e31f8f157d", features = ["encryption"] }
1616
tracing = "0.1"
1717
once_cell = "1.18.0"
1818
tokio = { version = "1.29.1", features = [ "rt-multi-thread" ] }

examples/offline-writes/example.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Database from "libsql";
2+
import reader from "readline-sync";
3+
4+
const dbPath = process.env.LIBSQL_DB_PATH;
5+
if (!dbPath) {
6+
throw new Error("Environment variable LIBSQL_DB_PATH is not set.");
7+
}
8+
const syncUrl = process.env.LIBSQL_SYNC_URL;
9+
if (!syncUrl) {
10+
throw new Error("Environment variable LIBSQL_SYNC_URL is not set.");
11+
}
12+
const authToken = process.env.LIBSQL_AUTH_TOKEN;
13+
14+
const options = { syncUrl: syncUrl, authToken: authToken, offline: true };
15+
const db = new Database(dbPath, options);
16+
17+
db.exec("CREATE TABLE IF NOT EXISTS guest_book_entries (text TEXT)");
18+
19+
const comment = reader.question("Enter your comment: ");
20+
21+
console.log(comment);
22+
23+
const stmt = db.prepare("INSERT INTO guest_book_entries (text) VALUES (?)");
24+
stmt.run(comment);
25+
console.log("max write replication index: " + db.maxWriteReplicationIndex());
26+
27+
const replicated = db.sync();
28+
console.log("frames synced: " + replicated.frames_synced);
29+
console.log("frame no: " + replicated.frame_no);
30+
31+
console.log("Guest book entries:");
32+
const rows = db.prepare("SELECT * FROM guest_book_entries").all();
33+
for (const row of rows) {
34+
console.log(" - " + row.text);
35+
}

examples/offline-writes/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "libsql-example",
3+
"version": "1.0.0",
4+
"description": "",
5+
"type": "module",
6+
"main": "index.js",
7+
"scripts": {
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"keywords": [],
11+
"author": "",
12+
"license": "ISC",
13+
"dependencies": {
14+
"libsql": "../..",
15+
"readline-sync": "^1.4.10"
16+
}
17+
}

index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function requireNative() {
2424

2525
const {
2626
databaseOpen,
27-
databaseOpenWithRpcSync,
27+
databaseOpenWithSync,
2828
databaseInTransaction,
2929
databaseClose,
3030
databaseSyncSync,
@@ -76,7 +76,8 @@ class Database {
7676
const encryptionKey = opts?.encryptionKey ?? "";
7777
const syncPeriod = opts?.syncPeriod ?? 0.0;
7878
const readYourWrites = opts?.readYourWrites ?? true;
79-
this.db = databaseOpenWithRpcSync(path, opts.syncUrl, authToken, encryptionCipher, encryptionKey, syncPeriod, readYourWrites);
79+
const offline = opts?.offline ?? false;
80+
this.db = databaseOpenWithSync(path, opts.syncUrl, authToken, encryptionCipher, encryptionKey, syncPeriod, readYourWrites, offline);
8081
} else {
8182
const authToken = opts?.authToken ?? "";
8283
const encryptionKey = opts?.encryptionKey ?? "";

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

promise.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function requireNative() {
3838

3939
const {
4040
databaseOpen,
41-
databaseOpenWithRpcSync,
41+
databaseOpenWithSync,
4242
databaseInTransaction,
4343
databaseClose,
4444
databaseSyncAsync,
@@ -79,7 +79,8 @@ class Database {
7979
}
8080
const encryptionKey = opts?.encryptionKey ?? "";
8181
const syncPeriod = opts?.syncPeriod ?? 0.0;
82-
this.db = databaseOpenWithRpcSync(path, opts.syncUrl, authToken, encryptionCipher, encryptionKey, syncPeriod);
82+
const offline = opts?.offline ?? false;
83+
this.db = databaseOpenWithSync(path, opts.syncUrl, authToken, encryptionCipher, encryptionKey, syncPeriod, offline);
8384
} else {
8485
const authToken = opts?.authToken ?? "";
8586
const encryptionKey = opts?.encryptionKey ?? "";

src/database.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,15 @@ impl Database {
6161
Ok(cx.boxed(db))
6262
}
6363

64-
pub fn js_open_with_rpc_sync(mut cx: FunctionContext) -> JsResult<JsBox<Database>> {
64+
pub fn js_open_with_sync(mut cx: FunctionContext) -> JsResult<JsBox<Database>> {
6565
let db_path = cx.argument::<JsString>(0)?.value(&mut cx);
6666
let sync_url = cx.argument::<JsString>(1)?.value(&mut cx);
6767
let sync_auth = cx.argument::<JsString>(2)?.value(&mut cx);
6868
let encryption_cipher = cx.argument::<JsString>(3)?.value(&mut cx);
6969
let encryption_key = cx.argument::<JsString>(4)?.value(&mut cx);
7070
let sync_period = cx.argument::<JsNumber>(5)?.value(&mut cx);
7171
let read_your_writes = cx.argument::<JsBoolean>(6)?.value(&mut cx);
72+
let offline = cx.argument::<JsBoolean>(7)?.value(&mut cx);
7273

7374
let cipher = libsql::Cipher::from_str(&encryption_cipher).or_else(|err| {
7475
throw_libsql_error(
@@ -95,16 +96,20 @@ impl Database {
9596
sync_url
9697
);
9798
let rt = runtime(&mut cx)?;
98-
let fut = libsql::Database::open_with_remote_sync_internal(
99-
db_path,
100-
sync_url,
101-
sync_auth,
102-
Some(version),
103-
read_your_writes,
104-
encryption_config,
105-
sync_period,
106-
);
107-
let result = rt.block_on(fut);
99+
let result = if offline {
100+
rt.block_on(libsql::Builder::new_synced_database(db_path, sync_url, sync_auth).build())
101+
} else {
102+
rt.block_on(async {
103+
let mut builder = libsql::Builder::new_remote_replica(db_path, sync_url, sync_auth);
104+
if let Some(encryption_config) = encryption_config {
105+
builder = builder.encryption_config(encryption_config);
106+
}
107+
if let Some(sync_period) = sync_period {
108+
builder = builder.sync_interval(sync_period);
109+
}
110+
builder.build().await
111+
})
112+
};
108113
let db = result.or_else(|err| cx.throw_error(err.to_string()))?;
109114
let conn = db
110115
.connect()

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
2828
)
2929
.try_init();
3030
cx.export_function("databaseOpen", Database::js_open)?;
31-
cx.export_function("databaseOpenWithRpcSync", Database::js_open_with_rpc_sync)?;
31+
cx.export_function("databaseOpenWithSync", Database::js_open_with_sync)?;
3232
cx.export_function("databaseInTransaction", Database::js_in_transaction)?;
3333
cx.export_function("databaseClose", Database::js_close)?;
3434
cx.export_function("databaseSyncSync", Database::js_sync_sync)?;

types/promise.d.ts.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)