Search code examples
linuxflutterwindowsdesktop-applicationsqflite

Flutter sqflite database location on desktop


How to change database file name to a custom path like your project folder in Flutter using Sqflite package on desktop?

When the following code is run in class named DatabaseHelper:

  Future<Database> _initDatabase() async {
    // Initialize sqflite as sqflite_common_ffi if you are on desktop
    dev.log(" In DatabaseHelper:\n    _initDatabase(): open database.");
    if (Platform.isWindows || Platform.isLinux) {
      dev.log("     On desktop.");
      sqfliteFfiInit();
    }else{
      dev.log("     On mobile.");
    }
    databaseFactory = databaseFactoryFfi;
    final databasePath = await databaseFactory.getDatabasesPath();
    print("Databese path: ======> $databasePath");

    final path = p.join(databasePath, SqlExp.fileName);

    return await databaseFactory.openDatabase(
      path,
      options: OpenDatabaseOptions(
        version: SqlExp.version,
        onCreate: _onCreate,
      ),
    );
  }

The output is:

[log]   In  DatabaseHelper:
[log]       _initDatabase(): open database.
[log]         On desktop.
flutter: Databese path: ======> /home/(pc-hostname)/Flutter/projects/(projectName)/.dart_tool/sqflite_common_ffi/databases

But the result that is requested is same think like: /home/(pc-hostname)/Flutter/projects/(projectName)/.databases/customPath

The getDatabasesPath() doesn't let you do that. Is there a function in Flutter or better in Dart (no external package if possible) that lets you get the current working directory, and if there is such a function, is it ok or more optimal to work with in the long run instead of the getDatabasesPath() function that came with the Sqflite package that is supposed to work well to gather, or am I mistaken?

I try getApplicationDocumentsDirectory() from path_provider package but, I'm expecting a custom path directory in to my project folder, I don't want the user get access to the database that easily.


Solution

  • You can use Dart's Directory class to get the current working directory.

    class DatabaseHelper {
      static final DatabaseHelper instance = DatabaseHelper._init();
      static Database? _database;
    
      DatabaseHelper._init();
    
      Future<Database> get database async {
        if (_database != null) return _database!;
    
        _database = await _initDatabase();
        return _database!;
      }
    
      Future<Database> _initDatabase() async {
        dev.log(" In DatabaseHelper:\n    _initDatabase(): open database.");
        if (Platform.isWindows || Platform.isLinux) {
          dev.log("     On desktop.");
          sqfliteFfiInit();
        } else {
          dev.log("     On mobile.");
        }
    
        databaseFactory = databaseFactoryFfi;
    
        // Get the current working directory
        final currentDir = Directory.current.path;
        dev.log("Current working directory: $currentDir");
    
        // Define your custom path
        final customPath = p.join(currentDir, '.databases', 'customPath');
        dev.log("Custom database path: $customPath");
    
        // Ensure the directory exists
        final customDir = Directory(customPath);
        if (!await customDir.exists()) {
          await customDir.create(recursive: true);
        }
    
        final path = p.join(customPath, SqlExp.fileName);
    
        return await databaseFactory.openDatabase(
          path,
          options: OpenDatabaseOptions(
            version: SqlExp.version,
            onCreate: _onCreate,
          ),
        );
      }
    
      Future _onCreate(Database db, int version) async {
        // Your database creation logic here
      }
    }