mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-21 09:04:19 +01:00
128 lines
3.6 KiB
Dart
128 lines
3.6 KiB
Dart
import 'package:turso_dart/src/helpers.dart';
|
|
import 'package:turso_dart/src/rust/api/connection.dart';
|
|
import 'package:turso_dart/src/rust/frb_generated.dart';
|
|
import 'package:turso_dart/src/rust/helpers/params.dart';
|
|
import 'package:turso_dart/src/rust/helpers/value.dart';
|
|
import 'package:turso_dart/src/statement.dart';
|
|
|
|
import 'rust/api/connect.dart' as c;
|
|
|
|
class TursoClient {
|
|
TursoClient(this.url);
|
|
|
|
TursoClient.memory() : url = ':memory:';
|
|
|
|
TursoClient.local(this.url);
|
|
|
|
final String url;
|
|
|
|
RustConnection? _connection;
|
|
|
|
/// Connect the database, must be called first after creation
|
|
Future<void> connect() async {
|
|
if (!RustLib.instance.initialized) {
|
|
await RustLib.init();
|
|
}
|
|
_connection = await c.connect(args: c.ConnectArgs(url: url));
|
|
}
|
|
|
|
/// Query the database, you can provide either named or positional parameters
|
|
///
|
|
/// # Args
|
|
/// * `sql` - SQL query
|
|
/// * `named` - Named parameters
|
|
/// * `positional` - Positional parameters
|
|
///
|
|
/// # Returns
|
|
/// Returns a list of object, eg: [{'id': 1, 'name': 'John'}, {'id': 2, 'name': 'Jane'}]
|
|
Future<List<Map<String, dynamic>>> query(
|
|
String sql, {
|
|
Map<String, dynamic>? named,
|
|
List<dynamic>? positional,
|
|
}) async {
|
|
if (_connection == null) throw Exception('Database is not connected');
|
|
final res = await _connection!.query(
|
|
sql: sql,
|
|
params: named != null
|
|
? Params.named(
|
|
named.entries
|
|
.map<(String, Value)>(
|
|
(entry) => (entry.key, toValue(entry.value)),
|
|
)
|
|
.toList(),
|
|
)
|
|
: positional != null
|
|
? Params.positional(positional.map(toValue).toList())
|
|
: const Params.none(),
|
|
);
|
|
return res.rows
|
|
.map(
|
|
(row) => Map.fromEntries(
|
|
row.entries.map(
|
|
(entry) => MapEntry(
|
|
entry.key,
|
|
entry.value.mapOrNull(
|
|
integer: (integer) => integer.field0,
|
|
real: (real) => real.field0,
|
|
text: (text) => text.field0,
|
|
blob: (blob) => blob.field0,
|
|
null_: (_) => null,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
.toList();
|
|
}
|
|
|
|
/// Execute the statement, you can provide either named or positional parameters
|
|
///
|
|
/// # Args
|
|
/// * `sql` - SQL query
|
|
/// * `named` - Named parameters
|
|
/// * `positional` - Positional parameters
|
|
///
|
|
/// # Returns
|
|
/// Number of rows affected by the statement
|
|
Future<int> execute(
|
|
String sql, {
|
|
Map<String, dynamic>? named,
|
|
List<dynamic>? positional,
|
|
}) async {
|
|
if (_connection == null) throw Exception('Database is not connected');
|
|
final res = await _connection!.execute(
|
|
sql: sql,
|
|
params: named != null
|
|
? Params.named(
|
|
named.entries
|
|
.map<(String, Value)>(
|
|
(entry) => (entry.key, toValue(entry.value)),
|
|
)
|
|
.toList(),
|
|
)
|
|
: positional != null
|
|
? Params.positional(positional.map(toValue).toList())
|
|
: const Params.none(),
|
|
);
|
|
return res.rowsAffected.toInt();
|
|
}
|
|
|
|
/// Create a prepared statement
|
|
///
|
|
/// # Args
|
|
/// * `sql` - SQL query
|
|
///
|
|
/// # Returns
|
|
/// Statement object
|
|
Future<Statement> prepare(String sql) async {
|
|
if (_connection == null) throw Exception('Database is not connected');
|
|
final inner = await _connection!.prepare(sql: sql);
|
|
return Statement(inner);
|
|
}
|
|
|
|
/// Close the database
|
|
Future<void> dispose() async {
|
|
_connection?.dispose();
|
|
}
|
|
}
|