Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,22 @@ NitroSQLite.loadFileAsync('myDatabase', '/absolute/path/to/file.sql').then(
);
```

## Encryption

Database encryption is supported through [SQLite Encryption Extension](https://sqlite.org/see) (SEE).

As SEE is a paid product, you need to patch the files `react-native-nitro-sqlite/cpp/sqlite/sqlite3.c` and `react-native-nitro-sqlite/cpp/sqlite/sqlite3.h` after installation using `bun patch react-native-nitro-sqlite`. Replace them with the `sqlite.h` and `sqlite3-see-<algorithm>.c` files from the SEE sources.

In addition, the [pre-processor flag](#enable-compile-time-options) `SQLITE_ENABLE_SEE` needs to be specified.

You can then use encryption, by passing an encryption key when opening the database

```typescript
import {open} from 'react-native-nitro-sqlite'

const db = open({name: 'myDb.sqlite', encryptionKey: 'SUPER_SECURE_ENCRYPTION_KEY'})
```

# TypeORM

This library is pretty barebones, you can write all your SQL queries manually but for any large application, an ORM is recommended.
Expand Down
4 changes: 4 additions & 0 deletions package/cpp/NitroSQLiteException.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const std::string NITRO_SQLITE_EXCEPTION_PREFIX = "[NativeNitroSQLiteException]"
enum NitroSQLiteExceptionType {
UnknownError,
DatabaseCannotBeOpened,
EncryptionNotEnabled,
DatabaseCannotBeDecrypted,
DatabaseNotOpen,
UnableToAttachToDatabase,
SqlExecutionError,
Expand All @@ -21,6 +23,8 @@ enum NitroSQLiteExceptionType {
inline std::unordered_map<NitroSQLiteExceptionType, std::string> exceptionTypeStrings = {
{UnknownError, "UnknownError"},
{DatabaseCannotBeOpened, "DatabaseCannotBeOpened"},
{EncryptionNotEnabled, "EncryptionNotEnabled"},
{DatabaseCannotBeDecrypted, "DatabaseCannotBeDecrypted"},
{DatabaseNotOpen, "DatabaseNotOpen"},
{UnableToAttachToDatabase, "UnableToAttachToDatabase"},
{SqlExecutionError, "SqlExecutionError"},
Expand Down
18 changes: 15 additions & 3 deletions package/cpp/operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace margelo::rnnitrosqlite {

std::map<std::string, sqlite3*> dbMap = std::map<std::string, sqlite3*>();

void sqliteOpenDb(const std::string& dbName, const std::string& docPath) {
void sqliteOpenDb(const std::string& dbName, const std::string& docPath, const std::optional<std::string>& encryptionKey) {
std::string dbPath = get_db_path(dbName, docPath);

int sqlOpenFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
Expand All @@ -31,9 +31,21 @@ void sqliteOpenDb(const std::string& dbName, const std::string& docPath) {

if (exit != SQLITE_OK) {
throw NitroSQLiteException(NitroSQLiteExceptionType::DatabaseCannotBeOpened, sqlite3_errmsg(db));
} else {
dbMap[dbName] = db;
}

if (encryptionKey.has_value()) {
#ifdef SQLITE_ENABLE_SEE
exit = sqlite3_key_v2(db, "main", encryptionKey.value().c_str(), -1);

if (exit != SQLITE_OK) {
throw NitroSQLiteException(NitroSQLiteExceptionType::DatabaseCannotBeDecrypted, sqlite3_errmsg(db));
}
#else
throw NitroSQLiteException(NitroSQLiteExceptionType::EncryptionNotEnabled, "Enable encryption by specifying SQLITE_ENABLE_SEE pre-processor flag and replacing sqlite.h / sqlite.c.");
#endif
}

dbMap[dbName] = db;
}

void sqliteCloseDb(const std::string& dbName) {
Expand Down
6 changes: 5 additions & 1 deletion package/cpp/operations.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#pragma once

#ifdef SQLITE_ENABLE_SEE
#define SQLITE_HAS_CODEC 1 // Enable SQLite encryption support
#endif

#include "types.hpp"

namespace margelo::rnnitrosqlite {

void sqliteOpenDb(const std::string& dbName, const std::string& docPath);
void sqliteOpenDb(const std::string& dbName, const std::string& docPath, const std::optional<std::string>& encryptionKey);

void sqliteCloseDb(const std::string& dbName);

Expand Down
4 changes: 2 additions & 2 deletions package/cpp/specs/HybridNitroSQLite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const std::string getDocPath(const std::optional<std::string>& location) {
return tempDocPath;
}

void HybridNitroSQLite::open(const std::string& dbName, const std::optional<std::string>& location) {
void HybridNitroSQLite::open(const std::string& dbName, const std::optional<std::string>& location, const std::optional<std::string>& encryptionKey) {
const auto docPath = getDocPath(location);
sqliteOpenDb(dbName, docPath);
sqliteOpenDb(dbName, docPath, encryptionKey);
}

void HybridNitroSQLite::close(const std::string& dbName) {
Expand Down
2 changes: 1 addition & 1 deletion package/cpp/specs/HybridNitroSQLite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class HybridNitroSQLite : public HybridNitroSQLiteSpec {

public:
// Methods
void open(const std::string& dbName, const std::optional<std::string>& location) override;
void open(const std::string& dbName, const std::optional<std::string>& location, const std::optional<std::string>& encryptionKey) override;

void close(const std::string& dbName) override;

Expand Down
6 changes: 5 additions & 1 deletion package/src/operations/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export function open(
options: NitroSQLiteConnectionOptions,
): NitroSQLiteConnection {
try {
HybridNitroSQLite.open(options.name, options.location)
HybridNitroSQLite.open(
options.name,
options.location,
options.encryptionKey,
)
openDatabaseQueue(options.name)
} catch (error) {
throw NitroSQLiteError.fromError(error)
Expand Down
2 changes: 1 addition & 1 deletion package/src/specs/NitroSQLite.nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { NativeQueryResult } from './NativeQueryResult.nitro'

export interface NitroSQLite
extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
open(dbName: string, location?: string): void
open(dbName: string, location?: string, encryptionKey?: string): void
close(dbName: string): void
drop(dbName: string, location?: string): void
attach(
Expand Down
1 change: 1 addition & 0 deletions package/src/typeORM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const typeORMDriver = {
options: {
name: string
location?: string
encryptionKey?: string
},
ok: (db: TypeOrmNitroSQLiteConnection) => void,
fail: (msg: string) => void,
Expand Down
1 change: 1 addition & 0 deletions package/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface NitroSQLiteConnectionOptions {
name: string
location?: string
encryptionKey?: string
}

export interface NitroSQLiteConnection {
Expand Down