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");
}
CodePudding user response:
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,
);
}
}
CodePudding user response:
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,
);
}