2017-05-23 100 views
6

Używam nowy Room Persistance Library wydany na tegorocznym Google I/O i to działa świetnie do tej pory, ale jakoś to nie jest możliwe złożenie zamówienia na wyniki z UNICODE lub ZLOKALIZOWANA . Jedyne, co działa to NOCASE, które jest bezużyteczne w moim przypadku.pokoju Trwałość Biblioteka Zapytanie sortowania nie zlokalizowane pracuje

Czy istnieje sposób na osiągnięcie tej funkcji?

@Dao 
public interface ContactDao { 

    @Query("SELECT * FROM contact ORDER BY lastName COLLATE LOCALIZED") 
    Flowable<List<Contact>> getAll(); 
} 

Gdybym zbudować kwerendę jak wyżej pojawia się błąd:

Error:(21, 29) error: There is a problem with the query: [SQLITE_ERROR] 
SQL error or missing database (no such collation sequence: LOCALIZED) 
+0

Jeśli dobrze rozumiem, aby używać 'UKLADAJ LOCALIZED', trzeba zadeklarować, że w ramach ograniczenie kolumny w instrukcji 'CREATE TABLE'. Wygląda na to, że możesz użyć 'Migracji' do zakodowania własnej instrukcji' CREATE TABLE', ale nie jest dla mnie jasne, jak utworzyć 'Migration' dla początkowego tworzenia tabeli (w porównaniu do aktualizacji). Nie wiem, czy to Ty zgłosiłeś [ten problem] (https://issuetracker.google.com/issues/62007004), ale powinienem mieć na to oko. – CommonsWare

+0

Witam, naprawiłeś to? –

+0

Niezupełnie ... w tej chwili sortuję listę, zanim ją wykorzystam. 'Collections.sort (nameOfYourList) {o1, o2 -> Collator.getInstance (Locale.GERMAN) .compare (o1.lastName, o2.lastName)}' – denwehrle

Odpowiedz

0

Użytkownika COLLATE w momencie kolumnie określić w następujący sposób

@ColumnInfo(collate = NOCASE) var name: String

To działa poprawnie dla mnie. Nie trzeba określać COLLATE w Query.

Również nie ma LOCALIZED zestawiać w Room

1

nie wiem dlaczego zlokalizowane sortowania nie jest realizowane (w pokoju wersji 1.0.0), kiedy to w dokumentacji (https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo.html#LOCALIZED). Znalazłem ten raport o problemie https://issuetracker.google.com/issues/68925249, który jest oznaczony jako naprawiony - ale prawdopodobnie nie został zwolniony.

Istnieje zatem brzydki sposób obejścia tego problemu - należy zdefiniować go w instrukcji CREATE. Można to zrealizować za pomocą wywołania zwrotnego w programie budującym bazy danych. Ale jest problem - musimy użyć create table, ponieważ sqlite nie obsługuje alter collate. A ponieważ tabela istnieje jeszcze w wywołaniu zwrotnym, musimy usunąć tę tabelę.

Jest moja realizacja (w Kotlin) - tworzenie oświadczenie musi skopiować definicję klasy jednostka również z indeksów:

@Database(entities = [(LocalityItem::class)], version = AppDatabase.DB_VERSION, exportSchema = false) 
abstract class AppDatabase : RoomDatabase() { 

    abstract fun localityDao(): LocalityDao 

    companion object { 
     const val DB_NAME : String = "app_db" 
     const val DB_VERSION : Int = 1 

     private var INSTANCE: AppDatabase? = null 

     private val CALLBACK: Callback = object : Callback() { 
      override fun onCreate(db: SupportSQLiteDatabase) { 
       db.execSQL("DROP TABLE `locality` ") 
       db.execSQL("CREATE TABLE `locality` (" 
         + " `id` INTEGER," 
         + " `type` INTEGER," 
         + " `name` TEXT COLLATE LOCALIZED, " 
         + " `row_index` INTEGER," 
         + " `col_index` INTEGER," 
         + " PRIMARY KEY(`id`)" 
         + ")") 
       db.execSQL("CREATE INDEX `index_locality_type` ON `locality` (`type`)") 
       db.execSQL("CREATE INDEX `index_locality_name` ON `locality` (`name`)") 
      } 
     } 

     fun getInstance(context : Context) : AppDatabase? { 
      if (INSTANCE == null) { 
       synchronized(AppDatabase::class) { 
        INSTANCE = Room.databaseBuilder(
          context.applicationContext, 
          AppDatabase::class.java, DB_NAME) 
          .addCallback(CALLBACK) 
          .build() 
       } 
      } 
      return INSTANCE 
     } 
    } 
}