flutter_sqlcipher 0.4.3
SQLCipher Database for Flutter #
This is a Flutter plugin that bundles and wraps SQLCipher for Android, an open-source extension to SQLite that provides transparent 256-bit AES encryption of database files.
Features #
-
Implements fully-encrypted SQLite databases stored on disk or in memory.
-
Supports booleans, doubles, integers, strings, blobs, and timestamps.
-
Provides a high-fidelity subset of the
android.database.sqlite
API to aid Android developers migrating to Flutter. -
Facilitates porting existing Android database code to Flutter.
Compatibility #
Android only, at present. (iOS support is planned.)
Examples #
Executing an arbitrary SQL statement #
await db.execSQL("DROP TABLE IF EXISTS links");
// Create a bookmark links table:
await db.execSQL("""
CREATE TABLE links (
id INTEGER PRIMARY KEY NOT NULL,
url TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NULL
)
""");
Executing an INSERT
statement
// Insert a new link into the table:
var linkID = db.insert(
table: "links",
values: <String, dynamic>{
"id": null, // auto-incremented ID assigned automatically
"url": "http://example.org/",
"created_at": DateTime.now().toUtc().millisecondsSinceEpoch ~/ 1000,
"updated_at": null,
},
);
Executing an UPDATE
statement
// Change the previously-inserted link from HTTP to HTTPS:
db.update(
table: "links",
values: <String, dynamic>{
"url": "https://example.org/",
"updated_at": DateTime.now().toUtc().millisecondsSinceEpoch ~/ 1000,
},
where: "id = ?",
whereArgs: <String>[linkID.toString()],
);
Executing a DELETE
statement
// Delete the previously-inserted link:
db.delete(
table: "links",
where: "id = ?",
whereArgs: <String>[linkID.toString()],
);
Executing an arbitrary SQL query #
for (var row in await db.rawQuery("SELECT 1 AS a, 2 as b, 3 AS c")) {
print(row); // prints: {a: 1, b: 2, c: 3}
}
Creating an in-memory database #
import 'package:flutter_sqlcipher/sqlite.dart';
var db = await SQLiteDatabase.createInMemory();
Creating an on-disk database #
This example also uses
Context
from the flutter_android package
to obtain the app's cache directory path.
import 'package:flutter_sqlcipher/sqlite.dart';
import 'package:flutter_android/android_content.dart' show Context;
var cacheDir = await Context.cacheDir;
await cacheDir.create(recursive: true);
var cacheFile = File("${cacheDir.path}/cache.db");
var db = await SQLiteDatabase.openOrCreateDatabase(cacheFile.path);
Using a bundled database from the app's assets #
(To be added.)
Frequently Asked Questions #
Which releases of SQLite and SQLCipher does this plugin bundle? #
SQLCipher for Android 4.0.0, SQLCipher 4.0.0, and SQLite 3.25.2.
Why this plugin instead of wrapping Android's native SQLite support? #
Two good reasons are:
-
Encryption. Android's native SQLite support does not feature database encryption. By using this plugin, you can trivially enable encryption for your app database, something likely appreciated by both you as well as your users.
-
Compatibility. Android's native SQLite version varies greatly depending on the specific Android release, from SQLite 3.4 (released in 2007) to SQLite 3.19 (released in 2017, bundled in Android 8.1). Further, some device manufacturers include different versions of SQLite on their devices. By using this plugin, you gain a consistent, predictable, and up-to-date version of SQLite for your app regardless of the Android release your app runs on.
How much does using this plugin increase my final app size? #
Due to the bundled SQLCipher native libraries, your final APK size currently
increases by about 6.7 MiB. We are actively
investigating
ways to reduce that footprint. (e.g.,
pruning .so
files
and using ProGuard).
Why are some of the android.database.sqlite
API methods missing?
We don't generally implement methods deprecated in the current Android API
level. For example, the
SQLiteDatabase#isDbLockedByOtherThreads()
method was deprecated long ago (in Android 4.1), so we have omitted it from
the Dart interface when implementing this plugin.
Caveats #
-
At present, iOS is not supported. This may eventually be addressed going forward by bundling and wrapping FMDB which includes SQLCipher support.
-
At present, cursors are fully materialized. This means that queries which return very large result sets will incur nontrivial overhead in the IPC transfer of the cursor data from Java to Dart. We are planning on adding windowed cursor and streaming support in a future major release. In the meanwhile,
OFFSET
andLIMIT
are your friends.
Reference #
sqlcipher
#
import 'package:flutter_sqlcipher/sqlcipher.dart';
sqlite
#
import 'package:flutter_sqlcipher/sqlite.dart';
SQLite.version
SQLiteCursor
SQLiteDatabase
SQLiteDatabase.create()
SQLiteDatabase.createInMemory()
SQLiteDatabase.deleteDatabase()
SQLiteDatabase.openDatabase()
SQLiteDatabase.openOrCreateDatabase()
SQLiteDatabase.releaseMemory()
SQLiteDatabase#inTransaction
SQLiteDatabase#maximumSize
SQLiteDatabase#pageSize
SQLiteDatabase#path
SQLiteDatabase#version
SQLiteDatabase#beginTransaction()
SQLiteDatabase#beginTransactionNonExclusive()
SQLiteDatabase#close()
SQLiteDatabase#delete()
SQLiteDatabase#disableWriteAheadLogging()
SQLiteDatabase#enableWriteAheadLogging()
SQLiteDatabase#endTransaction()
SQLiteDatabase#execSQL()
SQLiteDatabase#getAttachedDbs()
SQLiteDatabase#getMaximumSize()
SQLiteDatabase#getPageSize()
SQLiteDatabase#getPath()
SQLiteDatabase#getVersion()
SQLiteDatabase#insert()
SQLiteDatabase#insertOrThrow()
SQLiteDatabase#insertWithOnConflict()
SQLiteDatabase#isDatabaseIntegrityOk
SQLiteDatabase#isDbLockedByCurrentThread
SQLiteDatabase#isOpen
SQLiteDatabase#isReadOnly
SQLiteDatabase#isWriteAheadLoggingEnabled
SQLiteDatabase#needUpgrade()
SQLiteDatabase#query()
SQLiteDatabase#rawQuery()
SQLiteDatabase#replace()
SQLiteDatabase#replaceOrThrow()
SQLiteDatabase#setForeignKeyConstraintsEnabled()
SQLiteDatabase#setLocale()
SQLiteDatabase#setMaxSqlCacheSize()
SQLiteDatabase#setMaximumSize()
SQLiteDatabase#setPageSize()
SQLiteDatabase#setTransactionSuccessful()
SQLiteDatabase#setVersion()
SQLiteDatabase#update()
SQLiteDatabase#updateWithOnConflict()
SQLiteDatabase#validateSql()
SQLiteDatabase#yieldIfContendedSafely()
Cross-Reference #
Datatype Mappings #
Dart Class | Dart API | SQLite Storage Class | Notes |
---|---|---|---|
null | SQLiteCursor#isNull() | NULL | - |
bool | SQLiteCursor#getBool() | INTEGER | 0 , 1 |
int | SQLiteCursor#getInt() | INTEGER | - |
double | SQLiteCursor#getDouble() | REAL | - |
String | SQLiteCursor#getString() | TEXT | - |
Uint8List | SQLiteCursor#getBlob() | BLOB | - |
DateTime | SQLiteCursor#getDateTime() | TEXT | ISO-8601 "YYYY-MM-DD HH:MM:SS.SSS" |
DateTime | SQLiteCursor#getDateTime() | INTEGER | Seconds since 1970-01-01T00:00:00Z |
See Also #
- The sql_builder package implements a fluent DSL interface for constructing SQL queries.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.4.3] - 2019-03-13
Changed #
- Fixed a bug in
SQLiteDatabase#query()
(#4)
0.4.2 - 2019-03-13
Changed #
- Required flutter_android 0.4.0+
0.4.1 - 2019-02-28
No functional changes.
0.4.0 - 2019-02-14
Changed #
- Required Dart SDK 2.1+
- Required flutter_android 0.3.0+
0.3.5 - 2019-01-26
Changed #
- Added more examples to the README.
0.3.4 - 2019-01-26
Changed #
- Fixed a type error in
SQLiteDatabase#insertOrThrow()
- Fixed a type error in
SQLiteDatabase#replaceOrThrow()
- Fixed a type error in
SQLiteDatabase#update()
- Fixed a type error in
SQLiteDatabase#updateWithOnConflict()
0.3.3 - 2019-01-21
Changed #
- Added a default value for the bindings argument in
SQLiteDatabase#execSQL()
- Added a default value for the bindings argument in
SQLiteDatabase#rawQuery()
0.3.2 - 2018-12-08
Changed #
- Made
SQLiteCursor
iterable
0.3.1 - 2018-12-06
Changed #
- Fixed
Future<dynamic>
cast errors in several methods
0.3.0 - 2018-12-05
Changed #
SQLiteCursor#getBlob()
now returns aUint8List
, not aByteBuffer
0.2.5 - 2018-12-05
Added #
SQLiteDatabase#updateWithOnConflict()
method
0.2.4 - 2018-12-04
Added #
SQLiteDatabase#insertOrThrow()
methodSQLiteDatabase#insertWithOnConflict()
methodSQLiteDatabase#replaceOrThrow()
method
0.2.3 - 2018-12-04
Added #
SQLiteDatabase#delete()
methodSQLiteDatabase#insert()
methodSQLiteDatabase#replace()
methodSQLiteDatabase#update()
method
0.2.2 - 2018-12-04
Added #
SQLiteDatabase#setForeignKeyConstraintsEnabled()
methodSQLiteDatabase#query()
method
0.2.1 - 2018-12-03
Added #
SQLiteDatabase#disableWriteAheadLogging()
methodSQLiteDatabase#enableWriteAheadLogging()
method
0.2.0 - 2018-12-01
Changed #
- Upgraded from SQLCipher 3.5.9 to 4.0.0
0.1.6 - 2018-11-30
Added #
SQLiteClosable
interfaceSQLiteCursor#getBool()
methodSQLiteDatabase#close()
method
0.1.5 - 2018-11-30
Added #
SQLiteCursor#getDateTime()
methodSQLiteDatabase#isDatabaseIntegrityOk
getterSQLiteDatabase#isDbLockedByCurrentThread
getterSQLiteDatabase#getAttachedDbs()
methodSQLiteDatabase#validateSql()
methodSQLiteDatabase#yieldIfContendedSafely()
methodSQLiteDatatypeMismatchException
exception
0.1.4 - 2018-11-30
Added #
SQLiteDatabase#setMaxSqlCacheSize()
methodSQLiteDatabase#setMaximumSize()
methodSQLiteDatabase#setPageSize()
method
Changed #
- Made the second parameter to
SQLiteDatabase#rawQuery()
optional
0.1.3 - 2018-11-29
Added #
SQLiteDatabase.releaseMemory()
methodSQLiteDatabase#setTransactionSuccessful()
methodSQLiteDatabase#setVersion()
method
0.1.2 - 2018-11-23
Added #
SQLiteDatabase#inTransaction
getterSQLiteDatabase#maximumSize
getterSQLiteDatabase#pageSize
getterSQLiteDatabase#getMaximumSize()
methodSQLiteDatabase#getPageSize()
methodSQLiteDatabase#needUpgrade()
method
Changed #
- Added an optional parameter to
SQLiteDatabase#execSQL()
0.1.1 - 2018-11-23
Added #
SQLiteDatabase#beginTransaction()
methodSQLiteDatabase#beginTransactionNonExclusive()
methodSQLiteDatabase#endTransaction()
method
0.1.0 - 2018-11-22
Added #
SQLCipher.version
getterSQLite.version
getterSQLiteCursor
class and methodsSQLiteDatabase
classSQLiteDatabase.*
constantsSQLiteDatabase.create()
methodSQLiteDatabase.createInMemory()
methodSQLiteDatabase.deleteDatabase()
methodSQLiteDatabase.openDatabase()
methodSQLiteDatabase.openOrCreateDatabase()
methodSQLiteDatabase#path
getterSQLiteDatabase#version
getterSQLiteDatabase#execSQL()
methodSQLiteDatabase#getPath()
methodSQLiteDatabase#getVersion()
methodSQLiteDatabase#isOpen
getterSQLiteDatabase#isReadOnly
getterSQLiteDatabase#isWriteAheadLoggingEnabled
getterSQLiteDatabase#rawQuery()
methodSQLiteDatabase#setLocale()
method
flutter_sqlcipher_example #
Demonstrates how to use the flutter_sqlcipher plugin.
Screenshot #
Use this package as a library
1. Depend on it
Add this to your package's pubspec.yaml file:
dependencies:
flutter_sqlcipher: ^0.4.3
2. Install it
You can install packages from the command line:
with Flutter:
$ flutter pub get
Alternatively, your editor might support flutter pub get
.
Check the docs for your editor to learn more.
3. Import it
Now in your Dart code, you can use:
import 'package:flutter_sqlcipher/sqlcipher.dart';
import 'package:flutter_sqlcipher/sqlite.dart';
Popularity:
Describes how popular the package is relative to other packages.
[more]
|
70
|
Health:
Code health derived from static analysis.
[more]
|
100
|
Maintenance:
Reflects how tidy and up-to-date the package is.
[more]
|
100
|
Overall:
Weighted score of the above.
[more]
|
85
|
We analyzed this package on Dec 13, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:
- Dart: 2.7.0
- pana: 0.13.1+4
- Flutter: 1.12.13+hotfix.4
Dependencies
Package | Constraint | Resolved | Available |
---|---|---|---|
Direct dependencies | |||
Dart SDK | >=2.1.0 <3.0.0 | ||
flutter | 0.0.0 | ||
flutter_android | ^0.4.0 | 0.4.0 | |
meta | ^1.1.6 | 1.1.8 | |
Transitive dependencies | |||
collection | 1.14.11 | 1.14.12 | |
platform | 2.2.1 | ||
sky_engine | 0.0.99 | ||
typed_data | 1.1.6 | ||
vector_math | 2.0.8 | ||
Dev dependencies | |||
flutter_test | |||
test | >=1.3.4 <2.0.0 |