-
-
Notifications
You must be signed in to change notification settings - Fork 667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add expo-sqlite, the ability to test it, and a promisifying wrapper #5184
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
22c77ef
storage [nfc]: Make src/storage/ for below-Redux storage layers
gnprice 995422a
deps: Add expo-sqlite
gnprice 59f7903
expo-sqlite types: Mark a read-only array
gnprice 6a9564c
deps: Add sqlite3 as a dev-dependency
gnprice a7d19c0
deps: Force sqlite3 to use a recent node-gyp
gnprice 007dea3
sqlite3: Add type definitions, as a .js.flow rather than libdef
gnprice 6634190
sqlite3: Write a quick smoke-test to show it's working in Jest
gnprice 9c61edb
expo-sqlite tests: Get a working `immediate` in Jest
gnprice 04805f8
expo-sqlite tests: Write a mock version of expo-sqlite
gnprice ded9cb9
expo-sqlite tests: Basic transactions tests
gnprice 21736e9
expo-sqlite tests [nfc]: Simplifying helpers to bridge callbacks vs. …
gnprice 102c6da
expo-sqlite tests: Demo the broken asynchrony handling
gnprice d0fcdb7
mock-immediate: Give `immediate` a mockier mock
gnprice 0804092
mock-expo-sqlite: Add allowUnhandled
gnprice 9af36d1
expo-sqlite tests: Show transactions' (non-)handling of exceptions
gnprice ce2a3da
sqlite: Write a simple promisifying wrapper over expo-sqlite
gnprice 328963e
sqlite: Properly handle `await` in transactions
gnprice 88e46d5
sqlite: Properly handle app-level errors in transactions
gnprice File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
// `flowgen --no-inexact --interface-records node_modules/expo-sqlite/build/SQLite.types.d.ts` | ||
// from expo-sqlite 10.0.3 | ||
// with s/export type/declare export type/g, and as noted with "Zulip fix" below | ||
declare module 'expo-sqlite/build/SQLite.types' { | ||
/** | ||
* Flowtype definitions for SQLite.types | ||
* Generated by Flowgen from a Typescript Definition | ||
* Flowgen v1.14.1 | ||
*/ | ||
|
||
declare export type Window = {| | ||
openDatabase?: ( | ||
name: string, | ||
version: string, | ||
displayName: string, | ||
estimatedSize: number, | ||
creationCallback?: DatabaseCallback | ||
) => Database, | ||
|}; | ||
declare export type DatabaseCallback = (database: Database) => void; | ||
/** | ||
* `Database` objects are returned by calls to `SQLite.openDatabase()`. Such an object represents a | ||
* connection to a database on your device. | ||
*/ | ||
declare export type Database = {| | ||
version: string, | ||
|
||
/** | ||
* Execute a database transaction. | ||
* @param callback A function representing the transaction to perform. Takes a Transaction | ||
* (see below) as its only parameter, on which it can add SQL statements to execute. | ||
* @param errorCallback Called if an error occurred processing this transaction. Takes a single | ||
* parameter describing the error. | ||
* @param successCallback Called when the transaction has completed executing on the database. | ||
*/ | ||
transaction( | ||
callback: SQLTransactionCallback, | ||
errorCallback?: SQLTransactionErrorCallback, | ||
successCallback?: () => void | ||
): void, | ||
readTransaction( | ||
callback: SQLTransactionCallback, | ||
errorCallback?: SQLTransactionErrorCallback, | ||
successCallback?: () => void | ||
): void, | ||
|}; | ||
declare export type SQLTransactionCallback = (transaction: SQLTransaction) => void; | ||
declare export type SQLTransactionErrorCallback = (error: SQLError) => void; | ||
/** | ||
* A `SQLTransaction` object is passed in as a parameter to the `callback` parameter for the | ||
* `db.transaction()` method on a `Database` (see above). It allows enqueuing SQL statements to | ||
* perform in a database transaction. | ||
*/ | ||
declare export type SQLTransaction = {| | ||
/** | ||
* Enqueue a SQL statement to execute in the transaction. Authors are strongly recommended to make | ||
* use of the `?` placeholder feature of the method to avoid against SQL injection attacks, and to | ||
* never construct SQL statements on the fly. | ||
* @param sqlStatement A string containing a database query to execute expressed as SQL. The string | ||
* may contain `?` placeholders, with values to be substituted listed in the `arguments` parameter. | ||
* @param args An array of values (numbers or strings) to substitute for `?` placeholders in the | ||
* SQL statement. | ||
* @param callback Called when the query is successfully completed during the transaction. Takes | ||
* two parameters: the transaction itself, and a `ResultSet` object (see below) with the results | ||
* of the query. | ||
* @param errorCallback Called if an error occurred executing this particular query in the | ||
* transaction. Takes two parameters: the transaction itself, and the error object. | ||
*/ | ||
executeSql( | ||
sqlStatement: string, | ||
args?: $ReadOnlyArray<number | string>, // Zulip fix | ||
callback?: SQLStatementCallback, | ||
errorCallback?: SQLStatementErrorCallback | ||
): void, | ||
|}; | ||
declare export type SQLStatementCallback = ( | ||
transaction: SQLTransaction, | ||
resultSet: SQLResultSet | ||
) => void; | ||
declare export type SQLStatementErrorCallback = ( | ||
transaction: SQLTransaction, | ||
error: SQLError | ||
) => boolean; | ||
declare export type SQLResultSet = {| | ||
/** | ||
* The row ID of the row that the SQL statement inserted into the database, if a row was inserted. | ||
*/ | ||
insertId?: number, | ||
|
||
/** | ||
* The number of rows that were changed by the SQL statement. | ||
*/ | ||
rowsAffected: number, | ||
rows: SQLResultSetRowList, | ||
|}; | ||
declare export type SQLResultSetRowList = {| | ||
/** | ||
* The number of rows returned by the query. | ||
*/ | ||
length: number, | ||
|
||
/** | ||
* Returns the row with the given `index`. If there is no such row, returns `null`. | ||
* @param index Index of row to get. | ||
*/ | ||
item(index: number): any, | ||
|
||
/** | ||
* The actual array of rows returned by the query. Can be used directly instead of | ||
* getting rows through rows.item(). | ||
*/ | ||
_array: any[], | ||
|}; | ||
declare export class SQLError { | ||
static UNKNOWN_ERR: number; | ||
static DATABASE_ERR: number; | ||
static VERSION_ERR: number; | ||
static TOO_LARGE_ERR: number; | ||
static QUOTA_ERR: number; | ||
static SYNTAX_ERR: number; | ||
static CONSTRAINT_ERR: number; | ||
static TIMEOUT_ERR: number; | ||
code: number; | ||
message: string; | ||
} | ||
declare export type WebSQLDatabase = {| | ||
...$Exact<Database>, | ||
|
||
exec(queries: Query[], readOnly: boolean, callback: SQLiteCallback): void, | ||
|}; | ||
declare export type Query = {| | ||
sql: string, | ||
args: mixed[], | ||
|}; | ||
declare export type ResultSetError = {| | ||
error: Error, | ||
|}; | ||
/** | ||
* `ResultSet` objects are returned through second parameter of the `success` callback for the | ||
* `tx.executeSql()` method on a `SQLTransaction` (see above). | ||
*/ | ||
declare export type ResultSet = {| | ||
/** | ||
* The row ID of the row that the SQL statement inserted into the database, if a row was inserted. | ||
*/ | ||
insertId?: number, | ||
|
||
/** | ||
* The number of rows that were changed by the SQL statement. | ||
*/ | ||
rowsAffected: number, | ||
rows: {| | ||
[column: string]: any, | ||
|}[], | ||
|}; | ||
declare export type SQLiteCallback = ( | ||
error?: Error | null, | ||
resultSet?: (ResultSetError | ResultSet)[] | ||
) => void; | ||
} | ||
|
||
// `flowgen --no-inexact --interface-records node_modules/expo-sqlite/build/SQLite.d.ts` | ||
// from expo-sqlite 10.0.3 | ||
// with imports fixed up | ||
declare module 'expo-sqlite/build/SQLite' { | ||
/** | ||
* Flowtype definitions for SQLite | ||
* Generated by Flowgen from a Typescript Definition | ||
* Flowgen v1.14.1 | ||
*/ | ||
|
||
import type { WebSQLDatabase } from "expo-sqlite/build/SQLite.types"; | ||
|
||
/** | ||
* Open a database, creating it if it doesn't exist, and return a `Database` object. On disk, | ||
* the database will be created under the app's [documents directory](../filesystem), i.e. | ||
* `${FileSystem.documentDirectory}/SQLite/${name}`. | ||
* > The `version`, `description` and `size` arguments are ignored, but are accepted by the function | ||
* for compatibility with the WebSQL specification. | ||
* @param name Name of the database file to open. | ||
* @param version | ||
* @param description | ||
* @param size | ||
* @param callback | ||
* @return | ||
*/ | ||
declare export function openDatabase( | ||
name: string, | ||
version?: string, | ||
description?: string, | ||
size?: number, | ||
callback?: (db: WebSQLDatabase) => void | ||
): WebSQLDatabase; | ||
} | ||
|
||
declare module 'expo-sqlite' { | ||
declare export * from 'expo-sqlite/build/SQLite'; | ||
declare export * from 'expo-sqlite/build/SQLite.types'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat! I guess from now on we should reach for this first when a library doesn't have its own Flow or TypeScript types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah! I'm pretty happy with how this turned out.
I think for any of our existing libdefs, too, if we find ourselves spending any time writing changes to it then it'll probably make sense to first move it into this format (because it makes iteration so much more pleasant.) Should be a matter of (a) moving the file, (b) dropping the
declare module 'foo' {
and its}
, and (c) adding to the flowconfig line. And (a') splitting the file up into one per module, if there are several modules in the libdef file.That might even go for the libdef files we generate with flowgen. I think even some of the quirks of its output that we've had to fix up manually are because it's intended to be used to generate
.js.flow
files, not libdef files, so that could simplify our use of flowgen.