diff --git a/example/remote/main.go b/example/remote/main.go index 9080de8..31f17d3 100644 --- a/example/remote/main.go +++ b/example/remote/main.go @@ -23,9 +23,16 @@ func run() (err error) { return fmt.Errorf("TURSO_URL environment variable not set") } + sep := "?" authToken := os.Getenv("TURSO_AUTH_TOKEN") if authToken != "" { - dbUrl += "?authToken=" + authToken + dbUrl += sep + "authToken=" + authToken + sep = "&" + } + + remoteEncryptionKey := os.Getenv("TURSO_REMOTE_ENCRYPTION_KEY") + if remoteEncryptionKey != "" { + dbUrl += sep + "remoteEncryptionKey=" + remoteEncryptionKey } // Open database connection diff --git a/example/sync/main.go b/example/sync/main.go index 8b2d33d..5e988f0 100644 --- a/example/sync/main.go +++ b/example/sync/main.go @@ -15,13 +15,19 @@ func run() (err error) { return fmt.Errorf("TURSO_URL environment variable not set") } authToken := os.Getenv("TURSO_AUTH_TOKEN") + remoteEncryptionKey := os.Getenv("TURSO_REMOTE_ENCRYPTION_KEY") dir, err := os.MkdirTemp("", "libsql-*") if err != nil { return err } defer os.RemoveAll(dir) - connector, err := libsql.NewEmbeddedReplicaConnector(dir+"/test.db", primaryUrl, libsql.WithAuthToken(authToken)) + opts := []libsql.Option{libsql.WithAuthToken(authToken)} + if remoteEncryptionKey != "" { + opts = append(opts, libsql.WithRemoteEncryption(remoteEncryptionKey)) + } + + connector, err := libsql.NewEmbeddedReplicaConnector(dir+"/test.db", primaryUrl, opts...) if err != nil { return err } @@ -44,9 +50,14 @@ func run() (err error) { } }() + msg := "1. Sync with primary" + if remoteEncryptionKey != "" { + msg += " (encrypted db)" + } + for { fmt.Println("What would you like to do?") - fmt.Println("1. Sync with primary") + fmt.Println(msg) fmt.Println("2. Select from test table") fmt.Println("3. Insert row to test table") fmt.Println("4. Exit") diff --git a/libsql.go b/libsql.go index 975cfc4..fee3346 100644 --- a/libsql.go +++ b/libsql.go @@ -41,11 +41,11 @@ func init() { } type config struct { - authToken *string - readYourWrites *bool - encryptionKey *string + authToken *string + readYourWrites *bool + encryptionKey *string remoteEncryptionKey *string - syncInterval *time.Duration + syncInterval *time.Duration } type Option interface { @@ -217,8 +217,9 @@ func (d driver) OpenConnector(dbAddress string) (sqldriver.Connector, error) { fallthrough case "libsql": authToken := u.Query().Get("authToken") + remoteEncryptionKey := u.Query().Get("remoteEncryptionKey") u.RawQuery = "" - return openRemoteConnector(u.String(), authToken) + return openRemoteConnector(u.String(), authToken, remoteEncryptionKey) } return nil, fmt.Errorf("unsupported URL scheme: %s\nThis driver supports only URLs that start with libsql://, file:, https:// or http://", u.Scheme) } @@ -242,8 +243,8 @@ func openLocalConnector(dbPath string) (*Connector, error) { return &Connector{nativeDbPtr: nativeDbPtr}, nil } -func openRemoteConnector(primaryUrl, authToken string) (*Connector, error) { - nativeDbPtr, err := libsqlOpenRemote(primaryUrl, authToken) +func openRemoteConnector(primaryUrl, authToken, remoteEncryptionKey string) (*Connector, error) { + nativeDbPtr, err := libsqlOpenRemote(primaryUrl, authToken, remoteEncryptionKey) if err != nil { return nil, err } @@ -346,15 +347,26 @@ func libsqlOpenLocal(dataSourceName string) (C.libsql_database_t, error) { return db, nil } -func libsqlOpenRemote(url, authToken string) (C.libsql_database_t, error) { +func libsqlOpenRemote(url, authToken, remoteEncryptionKey string) (C.libsql_database_t, error) { connectionString := C.CString(url) defer C.free(unsafe.Pointer(connectionString)) authTokenNativeString := C.CString(authToken) defer C.free(unsafe.Pointer(authTokenNativeString)) + var remoteEncryptionKeyNativeString *C.char + if remoteEncryptionKey != "" { + remoteEncryptionKeyNativeString = C.CString(remoteEncryptionKey) + defer C.free(unsafe.Pointer(remoteEncryptionKeyNativeString)) + } + var db C.libsql_database_t var errMsg *C.char - statusCode := C.libsql_open_remote(connectionString, authTokenNativeString, &db, &errMsg) + var statusCode C.int + if remoteEncryptionKey == "" { + statusCode = C.libsql_open_remote(connectionString, authTokenNativeString, &db, &errMsg) + } else { + statusCode = C.libsql_open_remote_with_remote_encryption(connectionString, authTokenNativeString, remoteEncryptionKeyNativeString, &db, &errMsg) + } if statusCode != 0 { return nil, libsqlError(fmt.Sprint("failed to open remote database ", url), statusCode, errMsg) }