1

I am trying to get an async function _read() to run and the function does not pass the line: Reading reading = await helper.queryReading(rowId); in this function:

 _read() async {
    DatabaseHelper helper = DatabaseHelper.instance;
    int rowId = 1;
//lines above here executes
    Reading reading = await helper.queryReading(rowId); //this is the line it stops on 
// nothing below here is executed
    if (reading == null) {
      print('read row $rowId: empty');
    } else {
      print('read row $rowId: ${reading.reading}');
    }
  }

It is being called from the following function

class Profile {
  Widget getScreen(){
    print("Attempting to read db");
    _read();

    return  Scaffold( ...)

Here is my helper class:

import 'dart:ffi';
import 'dart:io';
import 'package:ema/Readings.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

//table structure
final String tableName = 'Readings';
final String databasecolumnId = '_id';
final String databaseReading = 'Reading';
final String databaseDate = 'Time';

class DatabaseHelper {
  //This is the name of the database file on disk
  static final _databaseName = "readings.db";

  //handles versioning for databases
  static final _databaseVersion = 1;

  //makes a singleton classs
  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  //allows only one item to access the database
  static Database _database;
  Future<Database> get database async {
    _database = await _initDatabase();
    return database;
  }

  //this opens and creates the database
  _initDatabase() async {
    // The path_provider plugin gets the right directory for Android or iOS.
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, _databaseName);
    // Open the database. Can also add an onUpdate callback parameter.
    return await openDatabase(path,
        version: _databaseVersion,
        onCreate: _onCreate);
  }



  //Creates the database
Future _onCreate(Database db, int version) async { 
    await db.execute(
        '''
        CREATE TABLE $tableName (
        $databasecolumnId INTEGER PRIMARY KEY,
        $databaseReading REAL NOT NULL,
        $databaseDate INTERGER NOT NULL
        )
        '''
    );
}
Future<int> insertReading(Reading reading) async {
    Database db = await database;
    int id = await db.insert(tableName, reading.toMap());
    return id;

}

//gets reading
Future<Reading> queryReading(int id) async {
    print("queryReading"); //gets here
  Database db = await database;
  print("Getting Db"); // not actually getting here
    List<Map> maps = await db.query(tableName,
        columns: [databasecolumnId, databaseReading, databaseDate],
        where: '$databasecolumnId = ?',
        whereArgs: [id]);
    if (maps.length > 0) {
      return Reading.fromMap(maps.first);
    }
  print('maps length : ${maps.length}');
    return null;
}

}

Here is my Readings class:


class Reading {
  int id;
  double reading;
  DateTime date;

  //constructor
  Reading({this.id, this.reading, this.date});

  Map<String, dynamic> toMap() {
    var map = <String, dynamic>{
      databaseReading: reading,
      databaseDate: date.millisecondsSinceEpoch,
    };
    if (id != null) {
      map[databasecolumnId] = id;
    }
    return map;
  }

  //extracts a node object from the map obect
  Reading.fromMap(Map<String, dynamic> map) {
    id = map[databasecolumnId];
    reading = map[databaseReading];
    date  = new DateTime.fromMillisecondsSinceEpoch(map [databaseDate]);
  }
}

10
  • are any exceptions thrown? Commented Apr 1, 2020 at 11:57
  • the problem isn't flutter not running your code, it waits or 'awaits' your 'queryReading' request and the line below will be executed after this one is finished, so you should check whats wrong with that line inside your helper class. Commented Apr 1, 2020 at 12:11
  • @KirillMatrosov none are thrown Commented Apr 1, 2020 at 13:25
  • @Henok as far as I'm aware the helper class is fine as no errors are thrown Commented Apr 1, 2020 at 13:27
  • @Osian do you mind posting your helper class code ? Commented Apr 1, 2020 at 13:43

1 Answer 1

1

Turns out there was a deadlock in getting the database. By putting a lock on it it worked. Here is the code to resolve it:

  ///declreation of the database
  Database _database;

  ///Gets the database ensuring that there are no locks currently on the database
  Future<Database> get database async {
    if (_database != null) return _database;
    _database = await _initDatabase();
    return _database;
  }
Sign up to request clarification or add additional context in comments.

Comments

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.