Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a function to move a db from assets #73

Merged
merged 2 commits into from
Mar 16, 2024
Merged
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
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);
};
Loading