Skip to content
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

adding support for MariaDB dialect #2521

Merged
merged 31 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6e36715
Update query_builder.dart
BananaMasterz Jul 18, 2023
485e59b
Update insert.dart
BananaMasterz Jul 18, 2023
bf75fdb
added support for MariaDB nested transactions
BananaMasterz Jul 18, 2023
125325b
update sqlTypeName for MariaDB
BananaMasterz Jul 18, 2023
910e063
add type literals for individual dialect in SqlDialect used in sqlTyp…
BananaMasterz Jul 19, 2023
1924722
auto increment support for MariaDB
BananaMasterz Jul 19, 2023
04b443c
add additionalMariaDBKeywords to be escaped for MariaDB dialect
BananaMasterz Jul 19, 2023
3fe50ff
remove duplicate keywords
BananaMasterz Jul 19, 2023
d2c3532
using backticks instead of double quotes to escape and adding bool ch…
BananaMasterz Jul 19, 2023
d1e7e11
remove bigIntType from SqlDialect
BananaMasterz Jul 19, 2023
82a8f84
isIn and isNotIn expression support for MariaDB dialect
BananaMasterz Jul 19, 2023
65d3d13
add test for isIn expression to avoid generating empty tuples
BananaMasterz Jul 20, 2023
20a2209
make SqlDialect.booleanType non-nullable
BananaMasterz Jul 20, 2023
43f75dd
KeyAction.noAction documentation
BananaMasterz Jul 21, 2023
72368c9
moving transaction savepoint statements to NoTransactionDelegate
BananaMasterz Jul 24, 2023
78d6064
introduce SqlDialect.escape DO NOT MERGE until Column.escapedName is …
BananaMasterz Jul 24, 2023
23b7b60
add drift_mariadb package
BananaMasterz Jul 24, 2023
18946f5
Scaffold MariaDb integration tests
simolus3 Jul 24, 2023
0963022
support for some MariaDB migration steps
BananaMasterz Jul 25, 2023
1c54320
Merge branch 'develop' into Banana-develop
simolus3 Jul 27, 2023
28e44cb
First support for MariaDB in compiled queries
simolus3 Jul 27, 2023
c2c0dc7
fix typo for supportsIndexedParameters documentation
BananaMasterz Jul 27, 2023
c642899
escape chosen alias based on dialect in JoinedSelectStatement
BananaMasterz Jul 27, 2023
2cca2f5
Desugar duplicate variables
simolus3 Jul 31, 2023
1a4ac27
Find variables reliably
simolus3 Aug 1, 2023
bb7e808
Apply format
simolus3 Aug 1, 2023
7678971
Fix drift tests
simolus3 Aug 2, 2023
8536891
Move migration tests directly into actions
simolus3 Aug 2, 2023
6bedc5f
Fix a few MariaDB integration tests
simolus3 Aug 2, 2023
6c8ec17
Re-generate migration code
simolus3 Aug 2, 2023
f700100
Add warning to MariaDB backend readme
simolus3 Aug 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,47 @@ jobs:
--health-retries 5
ports:
- 5432:5432
mariadb:
image: mariadb
env:
MARIADB_ROOT_PASSWORD: password
MARIADB_DATABASE: database
ports:
- 3306:3306
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/prepare
with:
dart_version: ${{ needs.setup.outputs.dart_version }}
- run: melos bootstrap --no-flutter
working-directory: .
- run: tool/misc_integration_test.sh
- name: Postgres integration tests
working-directory: extras/drift_postgres
run: |
dart pub upgrade
dart test
- name: MariaDB integration tests
working-directory: extras/drift_mariadb
continue-on-error: true
run: |
dart pub upgrade
dart test
- name: Integration test with built_value
working-directory: examples/with_built_value
run: |
dart pub upgrade
dart run build_runner build --delete-conflicting-outputs
- name: Integration test with modular generation
working-directory: examples/modular
run: |
dart pub upgrade
dart run build_runner build --delete-conflicting-outputs
dart run bin/example.dart
- name: Integration test for migrations example
working-directory: examples/migrations_example
run: |
dart pub upgrade
dart test

migration_integration_tests:
name: "Integration tests for migration tooling"
Expand Down
188 changes: 187 additions & 1 deletion drift/lib/sqlite_keywords.dart
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,187 @@ const additionalPostgresKeywords = <String>{
'USER',
};

/// A set of keywords that need to be escaped on mariadb and aren't contained
/// in [baseKeywords].
const additionalMariaDBKeywords = <String>{
'ACCESSIBLE',
'ASENSITIVE',
'AUTO_INCREMENT',
'BIGINT',
'BINARY',
'BLOB',
'BOTH',
'CALL',
'CHANGE',
'CHAR',
'CHARACTER',
'CONDITION',
'CONTINUE',
'CONVERT',
'CURRENT_ROLE',
'CURRENT_USER',
'CURSOR',
'DATABASES',
'DAY_HOUR',
'DAY_MICROSECOND',
'DAY_MINUTE',
'DAY_SECOND',
'DEC',
'DECIMAL',
'DECLARE',
'DELAYED',
'DELETE_DOMAIN_ID',
'DESCRIBE',
'DETERMINISTIC',
'DISTINCTROW',
'DIV',
'DO_DOMAIN_IDS',
'DOUBLE',
'DUAL',
'ELSEIF',
'ENCLOSED',
'ESCAPED',
'EXIT',
'FETCH',
'FLOAT',
'FLOAT4',
'FLOAT8',
'FORCE',
'FULLTEXT',
'GENERAL',
'GRANT',
'HIGH_PRIORITY',
'HOUR_MICROSECOND',
'HOUR_MINUTE',
'HOUR_SECOND',
'IGNORE_DOMAIN_IDS',
'IGNORE_SERVER_IDS',
'INFILE',
'INOUT',
'INSENSITIVE',
'INT',
'INT1',
'INT2',
'INT3',
'INT4',
'INT8',
'INTEGER',
'INTERVAL',
'ITERATE',
'KEYS',
'KILL',
'LEADING',
'LEAVE',
'LINEAR',
'LINES',
'LOAD',
'LOCALTIME',
'LOCALTIMESTAMP',
'LOCK',
'LONG',
'LONGBLOB',
'LONGTEXT',
'LOOP',
'LOW_PRIORITY',
'MASTER_HEARTBEAT_PERIOD',
'MASTER_SSL_VERIFY_SERVER_CERT',
'MAXVALUE',
'MEDIUMBLOB',
'MEDIUMINT',
'MEDIUMTEXT',
'MIDDLEINT',
'MINUTE_MICROSECOND',
'MINUTE_SECOND',
'MOD',
'MODIFIES',
'NO_WRITE_TO_BINLOG',
'NUMERIC',
'OPTIMIZE',
'OPTION',
'OPTIONALLY',
'OUT',
'OUTFILE',
'PAGE_CHECKSUM',
'PARSE_VCOL_EXPR',
'POSITION',
'PRECISION',
'PROCEDURE',
'PURGE',
'READ',
'READS',
'READ_WRITE',
'REAL',
'REF_SYSTEM_ID',
'REPEAT',
'REQUIRE',
'RESIGNAL',
'RETURN',
'RETURNING',
'REVOKE',
'RLIKE',
'ROW_NUMBER',
'SCHEMA',
'SCHEMAS',
'SECOND_MICROSECOND',
'SENSITIVE',
'SEPARATOR',
'SHOW',
'SIGNAL',
'SLOW',
'SMALLINT',
'SPATIAL',
'SPECIFIC',
'SQL',
'SQLEXCEPTION',
'SQLSTATE',
'SQLWARNING',
'SQL_BIG_RESULT',
'SQL_CALC_FOUND_ROWS',
'SQL_SMALL_RESULT',
'SSL',
'STARTING',
'STATS_AUTO_RECALC',
'STATS_PERSISTENT',
'STATS_SAMPLE_PAGES',
'STRAIGHT_JOIN',
'TERMINATED',
'TINYBLOB',
'TINYINT',
'TINYTEXT',
'TRAILING',
'TYPE',
'UNDO',
'UNLOCK',
'UNSIGNED',
'USAGE',
'USE',
'UTC_DATE',
'UTC_TIME',
'UTC_TIMESTAMP',
'VARBINARY',
'VARCHAR',
'VARCHARACTER',
'VARYING',
'WHILE',
'WRITE',
'XOR',
'YEAR_MONTH',
'ZEROFILL',
'BODY',
'ELSIF',
'GOTO',
'HISTORY',
'MINUS',
'PACKAGE',
'PERIOD',
'ROWNUM',
'ROWTYPE',
'SYSDATE',
'SYSTEM',
'SYSTEM_TIME',
'VERSIONING',
};

/// Returns whether [s] is an sql keyword by comparing it to the
/// [sqliteKeywords].
bool isSqliteKeyword(String s) => sqliteKeywords.contains(s.toUpperCase());
Expand All @@ -208,6 +389,11 @@ String escapeIfNeeded(String s, [SqlDialect dialect = SqlDialect.sqlite]) {
isKeyword |= additionalPostgresKeywords.contains(inUpperCase);
}

if (isKeyword || _notInKeyword.hasMatch(s)) return '"$s"';
if (dialect == SqlDialect.mariadb) {
isKeyword |= additionalMariaDBKeywords.contains(inUpperCase);
}

if (isKeyword || _notInKeyword.hasMatch(s)) return dialect.escape(s);

return s;
}
11 changes: 10 additions & 1 deletion drift/lib/src/dsl/columns.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ enum KeyAction {

/// No special action is taken when the parent key is modified or deleted from
/// the database.
///
/// For [SqlDialect.mariadb] this is synonym for [restrict].
noAction,
}

Expand All @@ -34,7 +36,7 @@ abstract class Column<T extends Object> extends Expression<T> {

/// The (unescaped) name of this column.
///
/// Use [escapedName] to access a name that's escaped in double quotes if
/// Use [escapedNameFor] to access a name that's escaped in double quotes if
/// needed.
String get name;

Expand All @@ -43,7 +45,14 @@ abstract class Column<T extends Object> extends Expression<T> {
/// In the past, this getter only used to add double-quotes when that is
/// really needed (for instance because [name] is also a reserved keyword).
/// For performance reasons, we unconditionally escape names now.
@Deprecated('Use escapedNameFor with the current dialect')
String get escapedName => '"$name"';

/// [name], but wrapped in double quotes or the DBMS-specific escape
/// identifier.
String escapedNameFor(SqlDialect dialect) {
return dialect.escape(name);
}
}

/// A column that stores int values.
Expand Down
15 changes: 13 additions & 2 deletions drift/lib/src/runtime/api/connection_user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -566,10 +566,21 @@ abstract class DatabaseConnectionUser {
/// Used by generated code to expand array variables.
String $expandVar(int start, int amount) {
final buffer = StringBuffer();
final mark = executor.dialect == SqlDialect.postgres ? '@' : '?';

final variableSymbol = switch (executor.dialect) {
SqlDialect.postgres => r'$',
_ => '?',
};
final supportsIndexedParameters =
executor.dialect.supportsIndexedParameters;

for (var x = 0; x < amount; x++) {
buffer.write('$mark${start + x}');
if (supportsIndexedParameters) {
buffer.write('$variableSymbol${start + x}');
} else {
buffer.write(variableSymbol);
}

if (x != amount - 1) {
buffer.write(', ');
}
Expand Down
21 changes: 21 additions & 0 deletions drift/lib/src/runtime/executor/helpers/delegates.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import 'dart:async' show FutureOr;
import 'package:drift/drift.dart';
import 'package:drift/src/runtime/executor/helpers/results.dart';

String _defaultSavepoint(int depth) => 'SAVEPOINT s$depth';

String _defaultRelease(int depth) => 'RELEASE s$depth';

String _defaultRollbackToSavepoint(int depth) => 'ROLLBACK TO s$depth';

/// An interface that supports sending database queries. Used as a backend for
/// drift.
///
Expand Down Expand Up @@ -132,13 +138,28 @@ class NoTransactionDelegate extends TransactionDelegate {
/// database engine.
final String rollback;

/// The statement that will create a savepoint for a given depth of a transaction
/// on this database engine.
final String Function(int depth) savepoint;

/// The statement that will release a savepoint for a given depth of a transaction
/// on this database engine.
final String Function(int depth) release;

/// The statement that will perform a rollback to a savepoint for a given depth
/// of a transaction on this database engine.
final String Function(int depth) rollbackToSavepoint;

/// Construct a transaction delegate indicating that native transactions
/// aren't supported and need to be emulated by issuing statements and
/// locking the database.
const NoTransactionDelegate({
this.start = 'BEGIN TRANSACTION',
this.commit = 'COMMIT TRANSACTION',
this.rollback = 'ROLLBACK TRANSACTION',
this.savepoint = _defaultSavepoint,
this.release = _defaultRelease,
this.rollbackToSavepoint = _defaultRollbackToSavepoint,
});
}

Expand Down
6 changes: 3 additions & 3 deletions drift/lib/src/runtime/executor/helpers/engines.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ class _StatementBasedTransactionExecutor extends _TransactionExecutor {
_StatementBasedTransactionExecutor.nested(
_StatementBasedTransactionExecutor this._parent, int depth)
: _delegate = _parent._delegate,
_startCommand = 'SAVEPOINT s$depth',
_commitCommand = 'RELEASE s$depth',
_rollbackCommand = 'ROLLBACK TO s$depth',
_startCommand = _parent._delegate.savepoint(depth),
_commitCommand = _parent._delegate.release(depth),
_rollbackCommand = _parent._delegate.rollbackToSavepoint(depth),
super(_parent._db);

@override
Expand Down
Loading
Loading