Support for Kysely with Expo SQLite (Next)
yarn add kysely-expo
or
npm i kysely-expo
Wrap the Expo app in the
By default, this library will automatically create tables with STRICT
mode enabled. This can be disabled by setting the disableStrictMode
option to true
.
STRICT
tables offer many advantages to keep data consistent, portable, and clean.
Supported types in STRICT mode:
INT
INTEGER
REAL
TEXT
BLOB
ANY
For more information, see https://www.sqlite.org/stricttables.html
SQLite has support for four basic types: string
, number
(integer), real
(decimal), and blob
(binary). SQLite doesn't support Date
, boolean
, object
, etc...
Using a boolean
as an example, SQLite will store it as a 1
/ 0 or "true"
/ "false". When you read data out, you will see a number or string - not a boolean.
Kysely Expo offers two converters to help make this conversion transparent.
Setting autoAffinityConversion
to true
will automatically attempt to manage these conversions for you.
Limitations:** Booleans are stored as "true"
or "false"
. If you control all your inputs and prohibit "true"
or "false" for string fields, this is generally completely safe.
Setting columnNameBasedConversion
to ColumnNameBasedConverter[]
will automatically map columns based on a naming convention to the types you specify.
For instance, if all of your columns that end with _at
are dates, you can add this:
{
type: "datetime",
match: (column) => column.endsWith("_at"),
},
Columns named "created_at
", "updated_at
", "deleted_at
" etc will all be converted to a Date
type. Rules are processed in the order they are defined.
Only one converter can be used at a time, specifying both will result in an exception being thrown.
Typescript | SQLite Type | Kysely Expo Type |
---|---|---|
boolean |
TEXT "true" | "false" |
SQLiteType.Boolean |
string |
TEXT |
SQLiteType.String |
Date |
TEXT ISO-8601 (YYYY-MM-DD HH:MM:SS) |
SQLiteType.DateTime |
number |
INTEGER or REAL |
SQLiteType.Integer or SQLiteType.Number |
any |
any |
SQLiteType.Any |
Uint8Array |
BLOB |
SQLiteType.Blob |
object |
TEXT |
SQLiteType.Json |
Using the blob
type is it possible to store binary data in your SQLite instance. If you are planning to store files, this is not recommended. It's better to store the files in the documents directory and store a path reference in your SQLite database.
import { ExpoDialect } from "kysely-expo";
import { Generated } from "kysely";
interface LogTable {
id: Generated<number>;
message: string;
created_at: Generated<Date>
}
interface Database {
logs: LogTable;
}
export default function App() {
return (
<KyselyProvider<Database>
database="logs.db"
autoAffinityConversion
debug
onInit={(database) =>
// run migrations here
}
>
<MainScreen />
</KyselyProvider>
);
}
function MainScreen() {
const { database } = useKysely<Database>();
const handleInsert = async () => {
const result = await database
.insertInto("logs")
.values({
message: "Important log message",
created_at: new Date(),
})
.execute();
}
return (
<View>
<Button onPress={handleInsert} title="Insert" />
</View>
);
}
const migrator = new Migrator({
db: data.database,
provider: new ExpoMigrationProvider({
migrations: {
"migration1": {
up: async (db: Kysely<Database>) => {
console.log("running migration 1");
const result = await db.schema
.createTable("logs")
.addColumn("id", "integer", (col) =>
col.primaryKey().autoIncrement()
)
.addColumn("message", SQLiteTypes.String, (col) => col.notNull())
.addColumn("created_at", SQLiteTypes.DateTime, (col) => col.notNull())
.execute();
},
},
},
}),
});
const result = await migrator.migrateToLatest();
A sample Expo app is included in the example
folder. It is a simple app that uses Expo SQLite and Kysely to create a database and perform basic CRUD operations. React Native applications do not support npm link
so yarn setup
will copy the files locally.
To run the example app:
yarn build
cd example
yarn install
yarn setup
npx expo start