Flutter: Where to place sqflite code inside my application?

834

No, it doesn't matter wherever you create the database.

You can create a file databaseServices.dart which manages the database service. It'll be easy for you to manage your code then.

In the cookbook, they are just showing an example, how you can use sqlflite.

But, however you should place this line WidgetsFlutterBinding.ensureInitialized(); in your main() method before anything, IF you are doing an asynchronous task in the main() method.

Update:

To perform CRUD in other files,

  1. import your databaseServices.dart file that file, in which you want to perform the CRUD.
import 'databaseServices.dart';

DataBaseServices db=DataBaseServices();// create an object (DataBaseServices is the name of the class)

//Now, you can access all the methods,

db.delete()//example

Alternatively, if you don't want to create a class in the databaseServices.dart file, and want to keep every function a top level function, then you can do the following.

import 'databaseServices.dart' as db;

//Now, you can access all the top level functions or variables.

db.delete()//example.

Update 2:-

To make database accessible to every function,

  1. move Future database outside the whatever () method, and place it just below the class name. (Making it global so that every function can access it), notice i removed the "final" keyword, because we are going to initialise it later, in the whatever method. Now, in the whatever method do what you were, but instead of final Future database = //yoir code, do this, database =//your code.. by doing this, you will be initialising the database variable, and as database variable is a global variable(declared outside any function, inside a class), any function can access it. But you have to keep in mind that, database has to be initialised before you call any other method which requires database, because if you will not call whatever () method before any other function, then the database won't be initialised, and hence your other functions won't work.

Example,

import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'counter.dart';

class DatabaseServices {
  Future<Database> database;//making database global so that every function inside the class can access it.
  void whatever() async {
    // Open the database and store the reference.
    database = openDatabase(
      // Set the path to the database.
      join(await getDatabasesPath(), 'counter_database.db'),
      // When the database is first created, create a table to store counters;
      onCreate: (db, version) {
        // Run the CREATE TABLE statement on the database.
        return db.execute(
          "CREATE TABLE counters(id INTEGER PRIMARY KEY, name TEXT, value INTEGER)",
        );
      },
      // Set the version. This executes the onCreate function and provides a
      // path to perform database upgrades and downgrades.
      version: 1,
    );
}//Function whatever () ends here
    // Define a function that inserts counters into the database.
    Future<void> insertCounter(Counter counter) async {
      // Get a reference to the database.
      final Database db = await database;
      // Insert the Counter into the correct table. Here, if a counter is inserted twice,
      // it replace any previous data.
      await db.insert(
        'counters',
        counter.toMap(),
        conflictAlgorithm: ConflictAlgorithm.replace,
      );
    }

    // A method that retrieves all the counters from the counters table.
    Future<List<Counter>> counters() async {
      // Get a reference to the database.
      final Database db = await database;
      // Query the table for all the Counters.
      final List<Map<String, dynamic>> maps = await db.query('counters');
      // Counvert the List<Map<String, dynamic>> into a List<Counter>
      return List.generate(maps.length, (i) {
        return Counter(
          id: maps[i]['id'],
          name: maps[i]['name'],
          value: maps[i]['value'],
        );
      });
    }

    // Method to update a Counter in the database
    Future<void> updateCounter(Counter counter) async {
      final db = await database;
      await db.update(
        'counters',
        counter.toMap(),
        where: "id = ?",
        whereArgs: [counter.id],
      );
    }

    //Delete a Counter from the database
    Future<void> deleteCounter(int id) async {
      final db = await database;
      await db.delete(
        'counters',
        where: "id = ?",
        whereArgs: [id],
      );
    }
  }


Now, since there are no nested functions, you can easily create an object of the class, and call the functions as you need easily :)

Share:
834
Admin
Author by

Admin

Updated on December 18, 2022

Comments

  • Admin
    Admin over 1 year

    I want to use sqflite in my app. To do this, I'm trying to follow this tutorial: https://flutter.dev/docs/cookbook/persistence/sqlite. However, I don't know where to place the code inside my application. In the tutorial, the code seems to be placed at the main() function - but, if I do that, how can I call the insert, update and delete methods at other files?

    Update:

    As suggested by @Madhavam Shahi, I created a file databaseServices.dart. Now, at the other file, I'm importing databaseServices.dart and trying to use it as below:

    import 'databaseServices.dart';
    DataBaseServices db=DataBaseServices();
    db.delete() //example
    

    However, it is not working. I think the databaseServices.dart is not structured the right way, but I can't spot the error. I know I must be making a very newbie mistake. Here is the code for the databaseServices.dart:

    import 'dart:async';
    import 'package:path/path.dart';
    import 'package:sqflite/sqflite.dart';
    import 'counter.dart';
    
    class DatabaseServices {
      
      void whatever() async {
        // Open the database and store the reference.
        final Future<Database> database = openDatabase(
          // Set the path to the database.
          join(await getDatabasesPath(), 'counter_database.db'),
          // When the database is first created, create a table to store counters;
          onCreate: (db, version) {
            // Run the CREATE TABLE statement on the database.
            return db.execute(
              "CREATE TABLE counters(id INTEGER PRIMARY KEY, name TEXT, value INTEGER)",
            );
          },
          // Set the version. This executes the onCreate function and provides a
          // path to perform database upgrades and downgrades.
          version: 1,
        );
    
        // Define a function that inserts counters into the database.
        Future<void> insertCounter(Counter counter) async {
          // Get a reference to the database.
          final Database db = await database;
          // Insert the Counter into the correct table. Here, if a counter is inserted twice,
          // it replace any previous data.
          await db.insert(
            'counters',
            counter.toMap(),
            conflictAlgorithm: ConflictAlgorithm.replace,
          );
        }
    
        // A method that retrieves all the counters from the counters table.
        Future<List<Counter>> counters() async {
          // Get a reference to the database.
          final Database db = await database;
          // Query the table for all the Counters.
          final List<Map<String, dynamic>> maps = await db.query('counters');
          // Counvert the List<Map<String, dynamic>> into a List<Counter>
          return List.generate(maps.length, (i) {
            return Counter(
              id: maps[i]['id'],
              name: maps[i]['name'],
              value: maps[i]['value'],
            );
          });
        }
    
        // Method to update a Counter in the database
        Future<void> updateCounter(Counter counter) async {
          final db = await database;
          await db.update(
            'counters',
            counter.toMap(),
            where: "id = ?",
            whereArgs: [counter.id],
          );
        }
    
        //Delete a Counter from the database
        Future<void> deleteCounter(int id) async {
          final db = await database;
          await db.delete(
            'counters',
            where: "id = ?",
            whereArgs: [id],
          );
        }
      }
    }
    
    
  • Admin
    Admin over 3 years
    So I created the file databaseServices.dart and placed my code there. To do that, I had to create a class and an async function to nest the code inside. Now, how can I call the insert, update and delete methods at other files?
  • Madhavam Shahi
    Madhavam Shahi over 3 years
    Please consider upvoting and accepting this as the answer if it helped :)
  • Admin
    Admin over 3 years
    Hi, @Madhavam Shahi, you are helping a lot! I just updated my question, can you please tell me what am I doing wrong?
  • Madhavam Shahi
    Madhavam Shahi over 3 years
    Umm, db.delete() is just an example, for deleting, you have a method named deleteCounter(), you have to call that method and pass an id, when you want to delete a counter. Hope it helps.
  • Admin
    Admin over 3 years
    I know it is an example. The problem is that, after creating the object with DataBaseServices db=DataBaseServices();, I can't access the object's methods. Tje only method available is whatever(), I can't see the other functions inside it. I tried to remove this method from the databaseServices.dart, but removing it results in various errors.
  • Madhavam Shahi
    Madhavam Shahi over 3 years
    Could you please show me how you're creating an object?
  • Admin
    Admin over 3 years
    As you can see, in databaseServices.dart I created a class DatabaseServices and, inside it, a method whatever(). The rest of the code, including the methods to include, update and delete, are all inside whatever(). Here is the problem: I am succeeding at creating the DatabaseServices object in the other file - but the object is only able to access the whatever() method, and not the other methods inside it. I tried to keep every function a top level function, but that results in two errors at databaseServices.dart: "Unexpected text 'await'" and...
  • Admin
    Admin over 3 years
    and the other error is "The argument type 'Future<String>' can't be assigned to the parameter type 'String'."
  • Admin
    Admin over 3 years
  • Admin
    Admin over 3 years
    Update 2 solved the problem! Thank you very much for your patience and time!!!