Retrieval
Explains synchronous and asynchronous retrieval from a SQLite database using DBFlow's query language and transaction system.
What this file does
Explains synchronous and asynchronous retrieval from a SQLite database using DBFlow's query language and transaction system.
When to use it
- You need to query a database synchronously with list or single results
- You want to run retrieval queries on a background queue to avoid locking
- You are using DBFlow's Model classes and want to map query results to objects
- You need custom query results or FlowCursorList/FlowTableList from a query
Assumes this stack
Retrieval
DBFlow provides a few ways to retrieve information from the database. Through the Model classes we can map this information to easy-to-use objects.
DBFlow provides a few different ways to retrieve information from the database. We can retrieve synchronously or asynchronous (preferred).
We can also use ModelView (read here) and @Index (read here) to perform faster retrieval on a set of data constantly queried.
Synchronous Retrieval
Using the SQLite query language we can retrieve data easily and expressively. To perform it synchronously:
databaseForTable<Employee> { db ->
// list
val employees = (select from Employee::class).queryList(db)
// single result, we apply a limit(1) automatically to get the result even faster.
val employee: Employee? = (select from Employee::class
where Employee_Table.name.eq("Andrew Grosner")).querySingle(db)
// can require result to get non-null if you know it exists
// throws a SQLiteException if missing
val employee: Employee? = (select from Employee::class
where Employee_Table.name.eq("Andrew Grosner")).requireSingle(db)
// get a custom list
val employees: List<AnotherTable> = (select from Employee::class)
.queryCustomList(database)
// custom object
val anotherObject: AnotherTable? = (select from Employee::class
where(Employee_Table.name.eq("Andrew Grosner")))
.queryCustomSingle()
// require custom object
val anotherObject: AnotherTable = (select from Employee::class
where(Employee_Table.name.eq("Andrew Grosner")))
.requireCustomSingle()
}
To query custom objects or lists, see how to do so in QueryModel.
Also you can query a FlowCursorList/FlowTableList from a query easily via queryCursorList() and the queryTableList() methods. To see more on these, go to Flow Lists.
Asynchronous Retrieval
DBFlow provides the very-handy Transaction system that allows you to place all calls to the DB in a background queue. Using this system, we recommend placing retrieval queries on this queue to help prevent locking and threading issues when using a database.
We wrap our queries in a beginTransactionAsync block, executing and providing call backs to the method as follows:
database.beginTransactionAsync { db ->
// body of transaction. Return the value you wish to pass into the Success callback.
(select from TestModel1::class
where TestModel1_Table.name.is("Async")).querySingle(db)
}
.execute(
ready = { transaction -> }, // called when transaction is ready to be executed.
success = { transaction, r -> }, // if successful
error = { transaction, throwable -> }, // any exception thrown is put here
completion = { transaction -> }) // always called success or failure
// or inverse is supported
(select from TestModel1::class
where TestModel1_Table.name.is("Async")).async { d -> querySingle(d) }
.execute { _, model: TestModel1? ->
}
A ITransaction<R> simply returns a result, R , which could be a query, or a result from multiple queries combined into one result.
By default the library uses an ordered queue that executes FIFO (first-in-first-out) and blocks itself until new Transaction are added. Each subsequent call to the database.beginTransactionAsync places a new transaction on this queue.
If you wish to customize and provide a different queue (or map it to an existing system), read up on Transactions. We also provide constructs such as coroutines and RX Observables to map to your team's needs.
What's inside
2 main sections (sync and async), 4 code examples, 6 query methods, 1 transaction callback pattern
Change this for your project
- Replace
EmployeeandEmployee_Tablewith your own model class and generated table - Replace
TestModel1andTestModel1_Tablewith your own model class and generated table - Replace
Andrew Grosnerwith your own query value
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Using a transaction callback with ready, success, error, and completion handlers
- Wrapping queries in
beginTransactionAsyncto run on a background queue
Related Documents
Variant Data Retrieval
Documents a system that queries gnomAD variant data via DataFrames, genomic intervals, or string representations using SQLite.
Lesson 4: Information Retrieval
Guides building a Flask app that fetches Bitcoin exchange rates from multiple APIs, stores them in SQLite, and displays best rates and historical trends.
Data Retrieval
Downloads UK electricity generation and pricing data from Electric Insights and Energy Charts APIs using the moepy library, then visualises fuel-mix time-series.
RETRIEVAL.md — Memory Scan Protocol
Defines a five-step internal memory retrieval protocol that surfaces results only in LiveHud gauges, never as visible logs.