Problem with SQLite

I’ve been trying to grasp sqlite and I keep running up to a problem on either database or table creation or access. I’m not sure where the actual problem lies and that’s part of the problem. I keep getting an error of table does not exist if when I create tables I specify “if not exist”. Moreover, I can’t seem to access the database/tables outside of the component I initially declare it in.

As an example I went through the sql example in the docs and if I separate the components into different files, it completely breaks. What am I missing? Can someone show the basic code where they declared a db, made a table, and then access that table in a different component in a different file than where it was initially created?

Edit: The code (simplified for the relevant parts)

The app returns a rootnavigator component which is a stack navigator using react-native-navigator npm and starts at teh homscreen component

HomeScreen

const db = SQLite.openDatabase({ name: 'site.db' });

export default class HomeScreen extends React.Component {

  componentDidMount() {
    db.transaction(tx => { tx.executeSql('CREATE TABLE IF NOT EXIST places (id INTEGER PRIMARY KEY NOT NULL, nombreAsegurado TEXT )')});
  }

render() {
    return (
      <View style={styles.container}>
        <Modal
          animationType="slide"
          transparent={false}
          visible={this.state.modalVisible}
          onRequestClose={() => { console.log("Modal has been closed.") }}
        >
          <SiteForm
            db={db}
            toggleVisible={this.toggleModal}
            updateSites={this.update.bind(this)}
          />
        </Modal>
   </View>
   )

  update = () => {
    console.log("Homescreen updating")
    this.place && this.place.update();
  }
}

SiteForm

export default class SiteForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      nombreAsegurado: '',
    }
  }

  addSite() {
    this.state.db.transaction(
      tx => {
        tx.executeSql('INSERT INTO places ( nombreAsegurado) VALUES (?)',
          [this.state.nombreAsegurado])
        tx.executeSql('select * from places', [], (_, { rows }) =>
          console.log(JSON.stringify(rows))
        );
      },
      (err) => { console.log("Addition Failed Message", err) },
      this.props.updateSites.bind(this)
    );
    console.log("Closing Modal");
  }

I found that I have to pass the db object to the SiteForm component which is where I’m actually adding entries to the db and I have errors If I just open the database. If I pass the db object I do not get the errors. But since I’m using a stack navigator I can’t pass the db object to other screens. Can anybody make sense of this?

Just export the db variable and use this in all your other screens. It needs to be a global singleton object.

One easy solution is to define a module that you use throughout your project:

// Database.js
import { SQLite } from 'expo';

module.exports = SQLite.openDatabase({ name: 'site.db' });

Then you can do:

import Database from './Database';

Database.transaction(...);
1 Like

Aside from making a new file (Database.js) and importing it instead of using db = SQLite.openDatabase({ name: ‘site.db’ }) am I missing a step? I did this and I get a Database not recognized or missing error.

Do you know of a pattern? This may seem silly but I’ve only worked with c# singletons and I’m unsure how to properly setup a global singleton object using es6. What I’ve found hasn’t worked so far.