Skip to content

Commit

Permalink
Merge pull request #73 from OP-Engineering/osp/assets-db
Browse files Browse the repository at this point in the history
Add a function to move a db from assets
  • Loading branch information
ospfranco authored Mar 16, 2024
2 parents ebfe5bd + 6887a81 commit a1053b4
Show file tree
Hide file tree
Showing 15 changed files with 126 additions and 9 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
47 changes: 47 additions & 0 deletions android/src/main/java/com/op/sqlite/OPSQLiteModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package com.op.sqlite
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.module.annotations.ReactModule;
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream

@ReactModule(name = OPSQLiteModule.NAME)
internal class OPSQLiteModule(context: ReactApplicationContext?) :
Expand Down Expand Up @@ -38,6 +42,49 @@ internal class OPSQLiteModule(context: ReactApplicationContext?) :
}
}

@ReactMethod(isBlockingSynchronousMethod = true)
override fun moveAssetsDatabase(name: String, extension: String): Boolean {
val context = reactApplicationContext
val assetsManager = context.assets

try {

// val assets = assetsManager.list("");
// Open the input stream for the asset file
val inputStream: InputStream = assetsManager.open("custom/$name.$extension")

// Create the output file in the documents directory
val databasesFolder = context
.getDatabasePath("defaultDatabase")
.absolutePath
.replace("defaultDatabase", "")

val outputFile = File(databasesFolder, "$name.$extension")

if (outputFile.exists()) {
return true
}

// Open the output stream for the output file
val outputStream: OutputStream = FileOutputStream(outputFile)

// Copy the contents from the input stream to the output stream
val buffer = ByteArray(1024)
var length: Int
while (inputStream.read(buffer).also { length = it } > 0) {
outputStream.write(buffer, 0, length)
}

// Close the streams
inputStream.close()
outputStream.close()

return true
} catch (exception: Exception) {
return false
}
}

override fun onCatalystInstanceDestroy() {
OPSQLiteBridge.instance.clearState()
}
Expand Down
4 changes: 4 additions & 0 deletions android/src/paper/java/com/op/sqlite/NativeOPSQLiteSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ public NativeOPSQLiteSpec(ReactApplicationContext reactContext) {
@ReactMethod(isBlockingSynchronousMethod = true)
@DoNotStrip
public abstract boolean install();

@ReactMethod(isBlockingSynchronousMethod = true)
@DoNotStrip
public abstract boolean moveAssetsDatabase(String name, String extension);
}
Binary file modified example/.yarn/install-state.gz
Binary file not shown.
Binary file not shown.
9 changes: 9 additions & 0 deletions example/android/link-assets-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"migIndex": 1,
"data": [
{
"path": "assets/sample.sqlite",
"sha1": "0f1675ac593b261b41a5144bc14f41163bd2a0c2"
}
]
}
Binary file added example/assets/sample.sqlite
Binary file not shown.
13 changes: 13 additions & 0 deletions example/ios/OPSQLiteExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
3B5A9E3FD2C56B364AF5A4F3 /* libPods-OPSQLiteExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EE3066EB7AAB7E17B1CAB50 /* libPods-OPSQLiteExample.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
022AA638EE144393ADDCAEC0 /* sample.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 96FD9FD0FC4F4540AC7A9CE6 /* sample.sqlite */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -29,6 +30,7 @@
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = OPSQLiteExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig"; path = "Target Support Files/Pods-OPSQLiteExample-OPSQLiteExampleTests/Pods-OPSQLiteExample-OPSQLiteExampleTests.release.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
96FD9FD0FC4F4540AC7A9CE6 /* sample.sqlite */ = {isa = PBXFileReference; name = "sample.sqlite"; path = "../assets/sample.sqlite"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -81,6 +83,7 @@
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
BBD78D7AC51CEA395F1C20DB /* Pods */,
A9BA4AF2CBC44B9BB28B8ABA /* Resources */,
);
indentWidth = 2;
sourceTree = "<group>";
Expand All @@ -106,6 +109,15 @@
path = Pods;
sourceTree = "<group>";
};
A9BA4AF2CBC44B9BB28B8ABA /* Resources */ = {
isa = "PBXGroup";
children = (
96FD9FD0FC4F4540AC7A9CE6 /* sample.sqlite */,
);
name = Resources;
sourceTree = "<group>";
path = "";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -169,6 +181,7 @@
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
022AA638EE144393ADDCAEC0 /* sample.sqlite in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion example/ios/OPSQLiteExample/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<string/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
Expand Down
9 changes: 9 additions & 0 deletions example/ios/link-assets-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"migIndex": 1,
"data": [
{
"path": "assets/sample.sqlite",
"sha1": "0f1675ac593b261b41a5144bc14f41163bd2a0c2"
}
]
}
1 change: 1 addition & 0 deletions example/react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ module.exports = {
root: path.join(__dirname, '..'),
},
},
assets: ['./assets/'],
};
15 changes: 13 additions & 2 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
import {dbSetupTests, queriesTests, runTests, blobTests} from './tests/index';
import {styled} from 'nativewind';
import {registerHooksTests} from './tests/hooks.spec';
import {open} from '@op-engineering/op-sqlite';
import {moveAssetsDatabase, open} from '@op-engineering/op-sqlite';
import clsx from 'clsx';
import {preparedStatementsTests} from './tests/preparedStatements.spec';
import {constantsTests} from './tests/constants.spec';
Expand Down Expand Up @@ -84,13 +84,23 @@ export default function App() {

const copyDbPathToClipboad = async () => {
const db = await open({name: 'dbPath.sqlite'});
db.execute('CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT)');
db.execute(
'CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT)',
);
const path = db.getDbPath();
await db.close();
console.warn(path);
Clipboard.setString(path);
};

const openAssetsDb = async () => {
const moved = moveAssetsDatabase('sample', 'sqlite');
console.log('moved', moved);
const db = open({name: 'sample.sqlite'});
const users = db.execute('SELECT * FROM User');
console.log('users', users.rows?._array);
};

const allTestsPassed = results.reduce((acc: boolean, r: any) => {
return acc && r.type !== 'incorrect';
}, true);
Expand All @@ -105,6 +115,7 @@ export default function App() {
title="Copy DB Path to clipboard"
onPress={copyDbPathToClipboad}
/>
<Button title="Open assets db" onPress={openAssetsDb} />
<Button title="Create 300k Record DB" onPress={createLargeDb} />
<Button title="Query 300k Records" onPress={queryLargeDb} />
{isLoading && <ActivityIndicator color={'white'} size="large" />}
Expand Down
17 changes: 17 additions & 0 deletions ios/OPSQLite.mm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,23 @@ - (NSDictionary *)getConstants {
return @true;
}

RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(moveAssetsDatabase:(NSString *)name extension:(NSString *)extension) {
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, true) objectAtIndex:0];
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:name ofType:extension];
NSString *destinationPath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", name, extension]];

NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:destinationPath]) {
return @true;
}

NSError *error;
[fileManager copyItemAtPath:sourcePath toPath:destinationPath error:&error];
if (error) {
return @false;
}
return @true;
}

#if RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
Expand Down
2 changes: 2 additions & 0 deletions src/NativeOPSQLite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface Spec extends TurboModule {
};

install(): boolean;

moveAssetsDatabase(name: string, extension: string): boolean;
}

export default TurboModuleRegistry.getEnforcing<Spec>('OPSQLite');
16 changes: 10 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,18 @@ declare global {
}

if (global.__OPSQLiteProxy == null) {
const OPSQLiteModule = NativeOPSQLite;

if (OPSQLiteModule == null) {
if (NativeOPSQLite == null) {
throw new Error('Base module not found. Maybe try rebuilding the app.');
}

// Check if we are running on-device (JSI)
if (global.nativeCallSyncHook == null || OPSQLiteModule.install == null) {
if (NativeOPSQLite.install == null) {
throw new Error(
'Failed to install op-sqlite: React Native is not running on-device. OPSQLite can only be used when synchronous method invocations (JSI) are possible. If you are using a remote debugger (e.g. Chrome), switch to an on-device debugger (e.g. Flipper) instead.'
);
}

// Call the synchronous blocking install() function
const result = OPSQLiteModule.install();
const result = NativeOPSQLite.install();
if (result !== true) {
throw new Error(
`Failed to install op-sqlite: The native OPSQLite Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`
Expand Down Expand Up @@ -470,3 +467,10 @@ export const open = (options: {
getDbPath: () => OPSQLite.getDbPath(options.name, options.location),
};
};

export const moveAssetsDatabase = (
dbName: string,
extension: string
): boolean => {
return NativeOPSQLite.moveAssetsDatabase(dbName, extension);
};

0 comments on commit a1053b4

Please sign in to comment.