Skip to content

Commit

Permalink
feat: named arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
justinlettau committed Jun 30, 2023
1 parent 36f7761 commit c515bbf
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 3 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

Useful utilities to augment [sqflite](https://pub.dev/packages/sqflite). Designed to be unobtrusive helpers, so you still access sqflite directly (not a wrapper).

## Features
## Usage

- Functions for working with `bool` values ([sqflite does not support bool](https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md#supported-sqlite-types))
### Bool utilities

## Usage
Sqflite does not support the `bool` type ([reference](https://github.com/tekartik/sqflite/blob/master/sqflite/doc/supported_types.md#supported-sqlite-types)).

```dart
import 'package:sqflite_ext/sqflite_ext.dart';
Expand All @@ -25,5 +25,17 @@ intToBool(1);
intToBoolOrNull(null);
// => null
```

### Named arguments

```dart
import 'package:sqflite_ext/sqflite_ext.dart';
final result = parseNamedArgs(
'SELECT * FROM demo WHERE id = :id',
{'id': 83},
);
// result.query => 'SELECT * FROM demo WHERE id = ?'
// result.arguments => [83]
```
7 changes: 7 additions & 0 deletions example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ void main() async {
// use with json_annotation (see class DemoItem below)
const item = DemoItem(isAwesome: true);
await db.insert('demo', item.toJson());

// query with named args
final p = parseNamedArgs(
'SELECT * FROM demo WHERE isAwesome = :status',
{'status': true},
);
await db.query(p.query, whereArgs: p.arguments);
}

@immutable
Expand Down
1 change: 1 addition & 0 deletions lib/sqflite_ext.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
library sqflite_ext;

export 'src/boolean_utils.dart';
export 'src/parse_named_args.dart';
25 changes: 25 additions & 0 deletions lib/src/parse_named_args.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/// A parsed raw query + argument values.
class QueryWithArgs {
QueryWithArgs(this.query, this.arguments);

/// Query with named arguments replace with placeholders (?).
String query;

/// List of query argument values.
List<Object?> arguments;
}

/// Parse a query with named arguments into a raw query + argument values.
QueryWithArgs parseNamedArgs(String query, Map<String, dynamic> params) {
final exp = RegExp(r":([\w]+)");
List<Object?> arguments = [];
RegExpMatch? match;

while ((match = exp.firstMatch(query)) != null) {
final name = query.substring(match!.start + 1, match.end);
query = query.replaceRange(match.start, match.end, '?');
arguments.add(params[name]);
}

return QueryWithArgs(query, arguments);
}
62 changes: 62 additions & 0 deletions test/src/parse_named_args_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:sqflite_ext/src/parse_named_args.dart';

void main() {
group('parseNamedArgs', () {
test('with no params', () {
final result = parseNamedArgs(
'SELECT * FROM demo',
{},
);

expect(result.query, 'SELECT * FROM demo');
expect(result.arguments, []);
});

test('with missing param', () {
final result = parseNamedArgs(
'SELECT * FROM demo WHERE id = :fail',
{},
);

expect(result.query, 'SELECT * FROM demo WHERE id = ?');
expect(result.arguments, [null]);
});

test('with a single param', () {
final result = parseNamedArgs(
'SELECT * FROM demo WHERE id = :id',
{'id': 83},
);

expect(result.query, 'SELECT * FROM demo WHERE id = ?');
expect(result.arguments, [83]);
});

test('with multiple different params', () {
final result = parseNamedArgs(
'SELECT * FROM demo WHERE a = :a AND b = :b AND c = :c',
{'a': 83, 'b': 'active', 'c': true},
);

expect(
result.query,
'SELECT * FROM demo WHERE a = ? AND b = ? AND c = ?',
);
expect(result.arguments, [83, 'active', true]);
});

test('with the same param multiple times', () {
final result = parseNamedArgs(
'SELECT * FROM demo WHERE a = :a AND b = :b AND c = :b',
{'a': 83, 'b': 'active'},
);

expect(
result.query,
'SELECT * FROM demo WHERE a = ? AND b = ? AND c = ?',
);
expect(result.arguments, [83, 'active', 'active']);
});
});
}

0 comments on commit c515bbf

Please sign in to comment.