1

I'm new to flutter and sqflite. For a project I was trying to use an existing database. I have kept my db file in a assest folder. When I run it on my emulator it shows nothing. Can someone tell me where did I do wrong? It's exactly not showing any error, but it's showing something like:

HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 
ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 
ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem 
ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 
ANDROID_EMU_YUV420_888_to_NV21 ANDROID_EMU_YUV_Cache 
ANDROID_EMU_async_unmap_buffer GL_OES_EGL_image_external_essl3 
GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr 
ANDROID_EMU_gles_max_version_3_0 
W/OpenGLRenderer( 5874): Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..
class DatabaseHelper {
  static final _databaseName = "lastRandomdb.db";
  static final _databaseVersion = 1;
  static final table = "Randomdb";
  static final columnEmail = "email";
  static final columnName = "name";

  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database _database;

  Future<Database> get database async {
    if (database != null) return database;
    _database = await _initDatabase();
    return _database;
  }

  _initDatabase() async {
    var databasepath = await getDatabasesPath();
    String path = join(databasepath, _databaseName);

    //check existing
    var exists = await databaseExists(path);
    if (!exists) {
      print("copy database start");
      try {
        await Directory(dirname(path)).create(recursive: true);
      } catch (_) {
        //copy
        ByteData data = await rootBundle.load(join("assets", _databaseName));
        List<int> bytes =
            data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

        //write
        await File(path).writeAsBytes(bytes, flush: true);
      }
    } else {
      print("opening exsisting database");
    }

    return await openDatabase(path, version: _databaseVersion);
  }

  //crud

  Future<List<Contact>> getAllContacts() async {
    Database db = await instance.database;
    final List<Map<String, dynamic>> map = await db.query(table);
    return List.generate(map.length, (index) {
      return Contact.fromMap(map[index]);
    });
  }

  Future<int> getCount() async {
    Database db = await instance.database;
    return Sqflite.firstIntValue(
        await db.rawQuery("SELECT COUNT(EMAIL) FROM $table"));
  }
}

this is my model file

final String COL_NAME = "name";
final String COL_EMAIL = "email";

class Contact {
  String name, email;
  Contact({this.name, this.email});

  Contact.map(dynamic obj1) {
    this.name = obj1['NAME'];
    this.email = obj1['EMAIL'];
  }

  Map<String, dynamic> toMap() {
    var map = <String, dynamic>{
      //method
      COL_NAME: name,
      COL_EMAIL: email,
    };
    return map;
  }

  Contact.fromMap(Map<String, dynamic> map) {
    //named constructor to return emoloyee model obj

    name = map[COL_NAME];
    email = map[COL_EMAIL];
  }

  @override
  String toString() {
    return 'Contact{name: $name, email: $email}';
  }
}

1 Answer 1

2

Ok let's evaluate your _initDatabase line by line

first you create the path and check if it exists

var databasepath = await getDatabasesPath();
String path = join(databasepath,_databaseName);

  //check existing
var exists = await databaseExists(path);

Seems good, then if it doesn't exist you want to copy it from the AssetFolder

try{
  await Directory(dirname(path)).create(recursive: true);
}catch(_){
  //copy
  ByteData data = await rootBundle.load(join("assets",_databaseName));
  List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

  //write
  await File(path).writeAsBytes(bytes, flush: true);
}

you try to create the Directory in the path (I don't know what method is dirname but I will believe it returns the path). If nothing fails then it will run

return await openDatabase(path,version: _databaseVersion);

It will enter the catch and copy the db from asset only if the creation of the Directory throws an error, is there a condition when it will fail that? If not then it will never try to copy the db. If you're sure that creating a Directory won't throw an error you should just run the code without the try catch

await Directory(dirname(path)).create(recursive: true); 
ByteData data = await rootBundle.load(join("assets",_databaseName));
List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); 
await File(path).writeAsBytes(bytes, flush: true);
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks..but i just tried without try and catch but didn't work for me
What's the size of your db? Did you save it in the asset folder and added that folder in the yaml file?
yes,,i saved it in the asset file.....and thanks.. i did followed your i removed the try catch..it didn't worked first time.. but after i did some changes then removing the try catch thing really worked..thank u
I read the example of sqflite about copying the db and even if they used the try catch to create the directory, they didn't wrap the rest of the code in the catch, they just left it as catch() {}, maybe that was all the misconception
yes,,, every code i checked online had used try catch..but..thank u so much for the help..was so frustrated
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.