pinchbv / floor

The typesafe, reactive, and lightweight SQLite abstraction for your Flutter applications
https://pinchbv.github.io/floor/
Apache License 2.0
951 stars 190 forks source link

findByKey() Returns Null When Primary Key is a String in Flutter 3.13.3 #780

Closed yousiffalaq closed 1 year ago

yousiffalaq commented 1 year ago

I’m using the Floor library in Flutter and I’ve encountered an issue with querying the database when the primary key is a string.

Sample code:

import 'package:floor/floor.dart';

@entity
class Cache {
  const Cache(this.key, this.value, this.maxAgeDateMs, this.createdAtDateMs);
  @PrimaryKey()
  final String key;

  @ColumnInfo(name: 'value')
  final String value;

  @ColumnInfo(name: 'max_age')
  final int maxAgeDateMs;

  @ColumnInfo(name: 'created_at')
  final int createdAtDateMs;

  @override
  String toString() {
    return 'Cache{key: $key, value: $value, maxAgeDateMs: $maxAgeDateMs, createdAtDateMs: $createdAtDateMs}';
  }
}
import 'package:floor/floor.dart';
import '../model/cache.dart';

@dao
abstract class CacheDao {
  @Query('SELECT * FROM cache')
  Future<List<Cache>> findAll();

  @Query('SELECT * FROM cache WHERE key = :key')
  Future<Cache?> findByKey(String key);

  @Query('SELECT * FROM cache WHERE value = :value')
  Future<Cache?> findByValue(String value);

  @Insert(onConflict: OnConflictStrategy.replace)
  Future<void> upsert(Cache cache);

  @Query('DELETE FROM cache WHERE key = :key')
  Future<void> removeByKey(String key);

  @Query('DELETE FROM cache WHERE max_age < :expiryDateMs')
  Future<void> removeExpired(int expiryDateMs);

  @Query('DELETE FROM cache WHERE key LIKE :keyLike')
  Future<void> removeWhereKeyLike(String keyLike);

  @Query('DELETE FROM cache WHERE 1')
  Future<void> removeAll();
}
  await cacheDao.upsert(Cache('key1', 'value1', 999999999, 56789));
  await cacheDao.upsert(Cache('key2', 'value2', 999999999, 56789));
  await cacheDao.upsert(Cache('key3', 'value3', 999999999, 56789));

  final caches = await cacheDao.findAll(); // working
  for (final cache in caches) {
    print(cache);
  }

  await cacheDao.findByKey('key1').then((value) => print(value)); // not working
  await cacheDao.findByValue('value2').then((value) => print(value)); // working
dependencies:
  flutter:
    sdk: flutter
  floor: ^1.4.2
  sqflite: ^2.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  floor_generator: ^1.4.2
  build_runner: ^2.1.2

flutter doctor -v

% flutter doctor -v
[✓] Flutter (Channel stable, 3.13.3, on macOS 13.1 22C65 darwin-arm64 (Rosetta))
    • Flutter version 3.13.3 on channel stable at
      /Users/yousif/development/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2524052335 (7 days ago), 2023-09-06 14:32:31 -0700
    • Engine revision b8d35810e9
    • Dart version 3.1.1
    • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/yousif/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      11.0.12+0-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.12.1

[✗] Chrome - develop for the web (Cannot find Chrome executable at
    /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Android Studio (version 2021.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      11.0.12+0-b1504.28-7817840)

[✓] VS Code (version 1.82.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.72.0

[✓] Connected device (2 available)
    • iPhone 14 Plus (mobile) • A80C29F6-7863-4344-91D4-CCCBEDAAAC29 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-16-4 (simulator)
    • macOS (desktop)         • macos                                •
      darwin-arm64 • macOS 13.1 22C65 darwin-arm64 (Rosetta)

[✓] Network resources
    • All expected network resources are available.

The issue is that findByKey() always returns null, even though I’m certain that there are records in the database with the provided key. Interestingly, if I change the primary key to an integer, findByKey() works as expected. However, for my use case, I need the primary key to be a string.

I’ve also noticed that other queries work fine. For example, findAll() returns all records in the ‘cache’ table as expected.

yousiffalaq commented 1 year ago

I just found out that I should use `` for the key like this: select * from cache where `key` = :key