select method

List<Row> select(
  1. String sql, [
  2. List<Object?> parameters = const []
])

Implementation

List<Row> select(String sql, [List<Object?> parameters = const []]) {
  final sqlPtr = sql.toNativeUtf8().cast<ffi.Char>();

  final ppStmt = calloc<ffi.Pointer<Sqlite3Stmt>>();
  try {
    final prepResult = sqlite3Prepare(
      this.db,
      sqlPtr,
      -1,
      0,
      ppStmt,
      ffi.nullptr,
    );

    if (prepResult != SQLITE_OK) {
      print("SQLITENOTOK $prepResult");
      throw Exception(this.errMsg());
    }

    final stmt = ppStmt.value;
    try {
      this._bindParams(stmt, parameters);

      final rowData = <Row>[];

      final colCount = sqlite3ColumnCount(stmt);

      while (sqlite3Step(stmt) == SQLITE_ROW) {
        rowData.add({});
        final row = rowData.last;

        for (var i = 0; i < colCount; i++) {
          final name = sqlite3ColumnName(stmt, i).cast<Utf8>().toDartString();
          final type = sqlite3ColumnType(stmt, i);
          dynamic Function(ffi.Pointer<Sqlite3Stmt>, int) func = this
              .getColFuncForType(type);
          var val = func(stmt, i);
          if (type == SQLITE_TEXT) {
            val = (val as ffi.Pointer<ffi.Char>).cast<Utf8>().toDartString();
          } else if (type == SQLITE_BLOB) {
            final blobPtr = (val as ffi.Pointer<ffi.Void>).cast<ffi.Uint8>();
            final int byteLength = sqlite3ColumnByte(stmt, i);

            if (blobPtr == ffi.nullptr || byteLength == 0) {
              val = Uint8List(0);
            } else {
              val = Uint8List.fromList(blobPtr.asTypedList(byteLength));
            }
          }
          row[name] = val;
        }
      }
      return rowData;
    } finally {
      sqlite3Finalize(stmt);
    }
  } finally {
    calloc.free(sqlPtr);
    calloc.free(ppStmt);
  }
}