Skip to content

Instantly share code, notes, and snippets.

@esafwan
Forked from sidferreira/WatermelonProvider.js
Last active October 10, 2022 12:47
Show Gist options
  • Save esafwan/32f92f10ca83a13b066838a4bd0953bb to your computer and use it in GitHub Desktop.
Save esafwan/32f92f10ca83a13b066838a4bd0953bb to your computer and use it in GitHub Desktop.
WatermelonDB preloaded db

This is the basic structure I'm using in an app.

getDatabasePath will handle any detail on unzip, copy, etc,

index will do all the usual dirty work, including withDatabase that won't explode if the database is missing

WatermelonProvider to cover original one til the DB is ready

import RNFS from "react-native-fs";
// Currently android will add `.db` to file name...
async function getDatabasePath(dbName) {
let dbPath = `${RNFS.DocumentDirectoryPath}/${dbName}`;
const exists = await RNFS.exists(dbPath.concat(".db"));
if (!exists) {
try {
await RNFS.copyFileAssets(dbName.concat(".db"), dbPath.concat(".db"));
} catch (e) {
console.log(">>> getDatabasePath error", e);
}
}
return dbPath;
}
export default getDatabasePath;
import RNFS from 'react-native-fs';
import * as RNZIP from 'react-native-zip-archive';
async function getDatabasePath(dbName) {
let sanitizedDbName = dbName;
if (!sanitizedDbName.endsWith(".db")) {
sanitizedDbName = sanitizedDbName.concat(".db");
}
let dbPath = `${RNFS.DocumentDirectoryPath}/${sanitizedDbName}`;
const exists = await RNFS.exists(dbPath);
if (!exists) {
const assetPath = `${RNFS.MainBundlePath}/${sanitizedDbName.replace(
".db",
".zip"
)}`;
const existsZip = await RNFS.exists(assetPath);
if (existsZip) {
const tmpPath = `${RNFS.DocumentDirectoryPath}/tmp`;
await RNZIP.unzip(assetPath, tmpPath);
await RNFS.moveFile(`${tmpPath}/${sanitizedDbName}`, dbPath);
await RNFS.unlink(tmpPath);
}
}
return dbPath;
}
export default getDatabasePath;
async function getDatabasePath(dbName) {
let fullDbName = dbName;
if (!fullDbName.endsWith('.db') && !fullDbName.includes('?')) {
fullDbName = fullDbName.concat('.db');
}
let dbPath = dbName.includes(process.cwd())
? fullDbName
: `${process.cwd()}/${fullDbName}`;
return dbPath;
}
export default getDatabasePath;
import getDatabasePath from './getDatabasePath';
const DEFAULT_DATABASE_NAME = 'watermelon';
const promises: { [key: string]: Promise<Database> } = {};
const instances: { [key: string]: Database } = {};
async function init(dbName: string = DEFAULT_DATABASE_NAME) {
const dbPath = await getDatabasePath(dbName);
const adapter = new SQLiteAdapter({
schema,
migrations,
dbName: dbPath,
});
const instance = new Database({
adapter,
modelClasses,
actionsEnabled: true,
});
instances[dbName] = instance;
// sync();
return db;
}
export const getDatabase = async (
dbName: string = DEFAULT_DATABASE_NAME,
) => {
if (!promises[dbName]) {
promises[dbName] = init(dbName);
}
const instance = await promises[dbName];
return instance;
};
// For _very_ specific uses
export const getDatabaseSync = (altDbName: string = DEFAULT_DATABASE_NAME) => {
return instances[altDbName];
};
// custom withDatabase to handle the possibility of not having the database just yet...
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
export const withDatabase = <T extends DatabaseProp>(
Wrapped: React.ComponentType<T>,
) => {
const WrappedComponent: React.ComponentType<Omit<T, DatabaseProp>> = (
props,
) => {
const database = useDatabase();
if (!database) {
return <View />;
}
return <Wrapped {...(props as T)} database={database} />;
};
return WrappedComponent;
};
import React, { ReactChild } from 'react';
import { Database } from '@nozbe/watermelondb';
import { getWatermelon } from 'app/utils/DBWatermelonOld/DBWatermelonOld';
import DatabaseProvider from '@nozbe/watermelondb/DatabaseProvider';
const WatermelonProvider = (props) => {
const watermelonRef = React.useRef();
const [database, setDatabase] = React.useState();
if (!watermelonRef.current) {
const promise = getWatermelon();
if (promise) {
watermelonRef.current = promise;
watermelonRef.current.then(setDatabase);
}
}
return database ? <DatabaseProvider database={database} {...props} /> : null;
};
export default WatermelonProvider;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment