The story:
In a react-native app we use react-native-sqlite-storage for dealing with sqlite3 both on iOS and Android.
This plugin enable us to deal with native sqlite implementation in that way:
var db = SQLite.openDatabase("test.db".....);
What would be the best approach to share the db-instance across multiple ponents? To give more details, but this is not part of this question, we use redux and have many action-files. Some of them need access to the database too.
In order to deal with a single opened instance of sqlite across all ponents and actions, and also to being more loosely coupled from native ponents, i built a class DataStorage encapsulating the storage-plugin. This class holdes an instance of the sqlite-database (using the react-native-sqlite-storage) and provides convenient methods to the application like "getUserByName()", "getAllItems" and so on.
To avoid multiple instances of this DataStorage class and also its inner sqlite-db-instance, i did the following:
- build the DataStorage class
- create a global variable residing only in DataStorage.js
- export a function sharedDataStorage() to the all the callers which need database access
Code of DataStorage.js
const SQLite = require('react-native-sqlite-storage');
const _dataStorage = null;
export class DataStorage {
constructor(autoCheckMigration = true, lang = 'en') {
console.log("DataStorage CTOR called");
if(_dataStorage !== null) {
throw 'There is already an instance of DataStorage alive';
}
// store this instance in a global variable
_dataStorage = this;
this.db = SQLite.openDatabase('myapp.db', '1.0', 'Myapps Database', 5 * 1024 * 1024, this.openCB, this.errorCB);
if (autoCheckMigration) {
this.checkDatabaseMigration(lang);
}
}
many_other_convenience_methods_here(...) {}
}
export function sharedDataStorage() {
return _dataStorage;
}
Applications root ponent:
In the applications root ponent i create the database instance calling its constructor.
export default class Application extends React.Component {
constructor(props) {
super(props);
this.setupDatabase();
}
render() {
return (
<Provider store={store}>
<ApplicationContainer />
</Provider>
);
}
setupDatabase() {
this.setState( {dataStorage: new DataStorage()} );
}
}
Some action_...js:
All other ponents and action-files now must gain access to this DataStorage-Class in this way:
import { sharedDataStorage } from '../data/dataStorage';
...
async function persistContacts(contacts) {
const dataStorage = sharedDataStorage();
contacts.forEach( (contact) => {
dataStorage.persistContact(contact);
});
}
This way is working pretty fine, although i am not sure, if there are better approaches sharing a database connection in react-native.
Which other possibilities are there?
The story:
In a react-native app we use react-native-sqlite-storage for dealing with sqlite3 both on iOS and Android.
This plugin enable us to deal with native sqlite implementation in that way:
var db = SQLite.openDatabase("test.db".....);
What would be the best approach to share the db-instance across multiple ponents? To give more details, but this is not part of this question, we use redux and have many action-files. Some of them need access to the database too.
In order to deal with a single opened instance of sqlite across all ponents and actions, and also to being more loosely coupled from native ponents, i built a class DataStorage encapsulating the storage-plugin. This class holdes an instance of the sqlite-database (using the react-native-sqlite-storage) and provides convenient methods to the application like "getUserByName()", "getAllItems" and so on.
To avoid multiple instances of this DataStorage class and also its inner sqlite-db-instance, i did the following:
- build the DataStorage class
- create a global variable residing only in DataStorage.js
- export a function sharedDataStorage() to the all the callers which need database access
Code of DataStorage.js
const SQLite = require('react-native-sqlite-storage');
const _dataStorage = null;
export class DataStorage {
constructor(autoCheckMigration = true, lang = 'en') {
console.log("DataStorage CTOR called");
if(_dataStorage !== null) {
throw 'There is already an instance of DataStorage alive';
}
// store this instance in a global variable
_dataStorage = this;
this.db = SQLite.openDatabase('myapp.db', '1.0', 'Myapps Database', 5 * 1024 * 1024, this.openCB, this.errorCB);
if (autoCheckMigration) {
this.checkDatabaseMigration(lang);
}
}
many_other_convenience_methods_here(...) {}
}
export function sharedDataStorage() {
return _dataStorage;
}
Applications root ponent:
In the applications root ponent i create the database instance calling its constructor.
export default class Application extends React.Component {
constructor(props) {
super(props);
this.setupDatabase();
}
render() {
return (
<Provider store={store}>
<ApplicationContainer />
</Provider>
);
}
setupDatabase() {
this.setState( {dataStorage: new DataStorage()} );
}
}
Some action_...js:
All other ponents and action-files now must gain access to this DataStorage-Class in this way:
import { sharedDataStorage } from '../data/dataStorage';
...
async function persistContacts(contacts) {
const dataStorage = sharedDataStorage();
contacts.forEach( (contact) => {
dataStorage.persistContact(contact);
});
}
This way is working pretty fine, although i am not sure, if there are better approaches sharing a database connection in react-native.
Which other possibilities are there?
Share Improve this question edited May 20, 2016 at 9:14 itinance asked May 20, 2016 at 9:06 itinanceitinance 12.4k8 gold badges64 silver badges109 bronze badges1 Answer
Reset to default 17I solve in this way:
database.js
'use strict';
import React from 'react';
import SQLite from 'react-native-sqlite-storage';
var database_name = "dbname.db";
var database_version = "1.0";
var database_displayname = "db";
var database_size = 200000;
let conn = SQLite.openDatabase(database_name, database_version, database_displayname, database_size, openDBHandler, errorDBHandler);
class Database {
getConnection() {
return conn;
}
}
module.exports = new Database();
Next in your ponent you can get the database connection with:
var connection = Database.getConnection();