skip to Main Content

I have the need to create a connection to a dynamically named database in a flutter app, how would I pass a parameter to a class with the name of the database, and return a connection to it?

I understand getters can’t accept parameters, and my attempt to add a setter function to set the _databaseName was unsuccessful.

I have a database class as follows:

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart' show join;
import 'dart:io' as io;
import 'package:path_provider/path_provider.dart';
class DatabaseHelper {
  static const _databaseName = "tinkershell.db";
  static const _databaseVersion = 1;
  DatabaseHelper._privateConstructor(); // make this a singleton class
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
  static Database?  _database; // only have a single app-wide reference to the database
  static String path = "";

  Future<Database> get database async => _database ??= await _initDatabase();

  _onOpen(Database db) async {
    //do something here later
  }

  Future<Database> _initDatabase() async {
    io.Directory documentDirectory = await getApplicationDocumentsDirectory();
    path = join(documentDirectory.path , _databaseName);
    return await openDatabase(
      join(path),
      version: _databaseVersion,
      onOpen: _onOpen,
    );
  }
}

and I’m making successfull calls to it using functions like this:

Future<void> createNewApplication() async {
  Database db = await DatabaseHelper.instance.database;
  final data = db.rawQuery(" SELECT * from myTable");
}

what I would like is to make a call like so:

Future<void> createNewApplication() async {
  Database db = await DatabaseHelper.instance.database("database1234");
  final data = db.rawQuery(" SELECT * from myTable");
}

2

Answers


  1. Would this work:

    
    import 'package:path/path.dart';
    import 'package:sqflite/sqflite.dart';
    import 'package:path/path.dart' show join;
    import 'dart:io' as io;
    import 'package:path_provider/path_provider.dart';
    class DatabaseHelper {
      static const _databaseName = "tinkershell.db";
      static const _databaseVersion = 1;
      DatabaseHelper._privateConstructor(); // make this a singleton class
      static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
      static Database?  _database; // only have a single app-wide reference to the database
      static String path = "";
    
      Future<Database> database(String databaseName) async {
       if (_databaseName==databaseName) return _database ??= await _initDatabase(databaseName);
       
      _databaseName=databaseName;
      return await _initDatabase(databaseName);
    }
    
      _onOpen(Database db) async {
        //do something here later
      }
    
      Future<Database> _initDatabase(String databaseName) async {
        io.Directory documentDirectory = await getApplicationDocumentsDirectory();
        path = join(documentDirectory.path , databaseName);
        return await openDatabase(
          join(path),
          version: _databaseVersion,
          onOpen: _onOpen,
        );
      }
    }
    
    
    Login or Signup to reply.
  2. Then instead of a getter use a method and pass database name, like this:

    Future<Database> database(String databaseName) async =>_database ??= await _initDatabase(databaseName);
    
    Future<Database> _initDatabase(String databaseName) async {
      io.Directory documentDirectory = await getApplicationDocumentsDirectory();
      path = join(documentDirectory.path, databaseName); // use passed databaseName
      return await openDatabase(
        join(path),
        version: _databaseVersion,
        onOpen: _onOpen,
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search