Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save samuelbezerrab/ce696383a6f2307ea9a4ac18d72f46ae to your computer and use it in GitHub Desktop.
Save samuelbezerrab/ce696383a6f2307ea9a4ac18d72f46ae 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';
aexport default sync function getDatabasePath(dbName: string = 'watermelon') {
const dbPath = `${RNFS.DocumentDirectoryPath}/${dbName}.db`;
// if must delete
// const alreadyExists = await RNFS.exists(dbPath);
// if (alreadyExists) {
// await RNFS.unlink(dbPath);
// }
const exists = await RNFS.exists(dbPath);
if (!exists) {
// const assetPathZip = `${dbName}.db.zip`;
const assetPath = `${dbName}.db`;
// RNZA.unzipAssets(assetPathZip, assetPath)
await RNFS.copyFileAssets(assetPath, dbPath);
}
return dbPath;
}
import RNFS from 'react-native-fs';
aexport default sync function getDatabasePath(dbName: string = 'watermelon') {
const dbPath = `${RNFS.DocumentDirectoryPath}/${dbName}.db`;
// if must delete
// const alreadyExists = await RNFS.exists(dbPath);
// if (alreadyExists) {
// await RNFS.unlink(dbPath);
// }
const exists = await RNFS.exists(dbPath);
if (!exists) {
// const assetPathZip = `${RNFS.MainBundlePath}/${dbName}.db.zip`;
const assetPath = `${RNFS.MainBundlePath}/${dbName}.db`;
// RNZA.unzip(assetPathZip, assetPath)
await RNFS.copyFile(assetPath, dbPath);
}
return dbPath;
}
export default async function getDatabasePath(dbName: string = 'watermelon') {
const dbPath = `${process.cwd()}/dbs/${dbName}.db`;
return dbPath;
}
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: React.ComponentType<{
children?: ReactChild;
}> = (props) => {
const watermelonRef = React.useRef<Promise<Database>>();
const [database, setDatabase] = React.useState<Database>();
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