mirror of https://github.com/AMT-Cheif/drift.git
Escape postgres keywords in generated SQL
This commit is contained in:
parent
ed964a7bf2
commit
deb1b91d41
|
@ -82,6 +82,16 @@ class SqlWriter extends NodeSqlBuilder {
|
||||||
return _out.toString();
|
return _out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isKeyword(String lexeme) {
|
||||||
|
switch (options.effectiveDialect) {
|
||||||
|
case SqlDialect.postgres:
|
||||||
|
return isKeywordLexeme(lexeme) || isPostgresKeywordLexeme(lexeme);
|
||||||
|
default:
|
||||||
|
return isKeywordLexeme(lexeme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FoundVariable? _findMoorVar(Variable target) {
|
FoundVariable? _findMoorVar(Variable target) {
|
||||||
return query!.variables.firstWhereOrNull(
|
return query!.variables.firstWhereOrNull(
|
||||||
(f) => f.variable.resolvedIndex == target.resolvedIndex);
|
(f) => f.variable.resolvedIndex == target.resolvedIndex);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: drift_dev
|
name: drift_dev
|
||||||
description: Dev-dependency for users of drift. Contains the generator and development tools.
|
description: Dev-dependency for users of drift. Contains the generator and development tools.
|
||||||
version: 2.5.1
|
version: 2.6.0-dev
|
||||||
repository: https://github.com/simolus3/drift
|
repository: https://github.com/simolus3/drift
|
||||||
homepage: https://drift.simonbinder.eu/
|
homepage: https://drift.simonbinder.eu/
|
||||||
issue_tracker: https://github.com/simolus3/drift/issues
|
issue_tracker: https://github.com/simolus3/drift/issues
|
||||||
|
@ -27,7 +27,7 @@ dependencies:
|
||||||
# Drift-specific analysis and apis
|
# Drift-specific analysis and apis
|
||||||
drift: '>=2.5.0 <2.6.0'
|
drift: '>=2.5.0 <2.6.0'
|
||||||
sqlite3: '>=0.1.6 <2.0.0'
|
sqlite3: '>=0.1.6 <2.0.0'
|
||||||
sqlparser: '^0.27.0'
|
sqlparser: '^0.28.0'
|
||||||
|
|
||||||
# Dart analysis
|
# Dart analysis
|
||||||
analyzer: ^5.2.0
|
analyzer: ^5.2.0
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift_dev/src/analysis/options.dart';
|
import 'package:drift_dev/src/analysis/options.dart';
|
||||||
import 'package:drift_dev/src/analysis/results/results.dart';
|
import 'package:drift_dev/src/analysis/results/results.dart';
|
||||||
import 'package:drift_dev/src/writer/queries/sql_writer.dart';
|
import 'package:drift_dev/src/writer/queries/sql_writer.dart';
|
||||||
|
@ -5,14 +6,14 @@ import 'package:sqlparser/sqlparser.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
void check(String sql, String expectedDart) {
|
void check(String sql, String expectedDart,
|
||||||
|
{DriftOptions options = const DriftOptions.defaults()}) {
|
||||||
final engine = SqlEngine();
|
final engine = SqlEngine();
|
||||||
final context = engine.analyze(sql);
|
final context = engine.analyze(sql);
|
||||||
final query = SqlSelectQuery('name', context, context.root, [], [],
|
final query = SqlSelectQuery('name', context, context.root, [], [],
|
||||||
InferredResultSet(null, []), null, null);
|
InferredResultSet(null, []), null, null);
|
||||||
|
|
||||||
final result =
|
final result = SqlWriter(options, query: query).write();
|
||||||
SqlWriter(const DriftOptions.defaults(), query: query).write();
|
|
||||||
|
|
||||||
expect(result, expectedDart);
|
expect(result, expectedDart);
|
||||||
}
|
}
|
||||||
|
@ -28,4 +29,11 @@ void main() {
|
||||||
test('escapes Dart characters in SQL', () {
|
test('escapes Dart characters in SQL', () {
|
||||||
check(r"SELECT '$hey';", r"'SELECT \'\$hey\''");
|
check(r"SELECT '$hey';", r"'SELECT \'\$hey\''");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('escapes postgres keywords', () {
|
||||||
|
check('SELECT * FROM user', "'SELECT * FROM user'");
|
||||||
|
check('SELECT * FROM user', "'SELECT * FROM \"user\"'",
|
||||||
|
options: DriftOptions.defaults(
|
||||||
|
dialect: DialectOptions(SqlDialect.postgres, null)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ class PreferenceConverter extends NullAwareTypeConverter<Preferences, String> {
|
||||||
'ORDER BY (SELECT COUNT(*) FROM friendships '
|
'ORDER BY (SELECT COUNT(*) FROM friendships '
|
||||||
'WHERE first_user = u.id OR second_user = u.id) DESC LIMIT :amount',
|
'WHERE first_user = u.id OR second_user = u.id) DESC LIMIT :amount',
|
||||||
'amountOfGoodFriends': 'SELECT COUNT(*) FROM friendships f WHERE '
|
'amountOfGoodFriends': 'SELECT COUNT(*) FROM friendships f WHERE '
|
||||||
'f.really_good_friends = 1 AND '
|
'f.really_good_friends = TRUE AND '
|
||||||
'(f.first_user = :user OR f.second_user = :user)',
|
'(f.first_user = :user OR f.second_user = :user)',
|
||||||
'friendshipsOf': ''' SELECT
|
'friendshipsOf': ''' SELECT
|
||||||
f.really_good_friends, "user".**
|
f.really_good_friends, "user".**
|
||||||
|
|
|
@ -555,7 +555,7 @@ abstract class _$Database extends GeneratedDatabase {
|
||||||
|
|
||||||
Selectable<int> amountOfGoodFriends(int user) {
|
Selectable<int> amountOfGoodFriends(int user) {
|
||||||
return customSelect(
|
return customSelect(
|
||||||
'SELECT COUNT(*) AS _c0 FROM friendships AS f WHERE f.really_good_friends = 1 AND(f.first_user = @1 OR f.second_user = @1)',
|
'SELECT COUNT(*) AS _c0 FROM friendships AS f WHERE f.really_good_friends = TRUE AND(f.first_user = @1 OR f.second_user = @1)',
|
||||||
variables: [
|
variables: [
|
||||||
Variable<int>(user)
|
Variable<int>(user)
|
||||||
],
|
],
|
||||||
|
@ -566,7 +566,7 @@ abstract class _$Database extends GeneratedDatabase {
|
||||||
|
|
||||||
Selectable<FriendshipsOfResult> friendshipsOf(int user) {
|
Selectable<FriendshipsOfResult> friendshipsOf(int user) {
|
||||||
return customSelect(
|
return customSelect(
|
||||||
'SELECT f.really_good_friends,"user"."id" AS "nested_0.id", "user"."name" AS "nested_0.name", "user"."birth_date" AS "nested_0.birth_date", "user"."profile_picture" AS "nested_0.profile_picture", "user"."preferences" AS "nested_0.preferences" FROM friendships AS f INNER JOIN users AS user ON user.id IN (f.first_user, f.second_user) AND user.id != @1 WHERE(f.first_user = @1 OR f.second_user = @1)',
|
'SELECT f.really_good_friends,"user"."id" AS "nested_0.id", "user"."name" AS "nested_0.name", "user"."birth_date" AS "nested_0.birth_date", "user"."profile_picture" AS "nested_0.profile_picture", "user"."preferences" AS "nested_0.preferences" FROM friendships AS f INNER JOIN users AS "user" ON "user".id IN (f.first_user, f.second_user) AND "user".id != @1 WHERE(f.first_user = @1 OR f.second_user = @1)',
|
||||||
variables: [
|
variables: [
|
||||||
Variable<int>(user)
|
Variable<int>(user)
|
||||||
],
|
],
|
||||||
|
|
|
@ -24,6 +24,10 @@ class NodeSqlBuilder extends AstVisitor<void, void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isKeyword(String lexeme) {
|
||||||
|
return isKeywordLexeme(lexeme);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitAggregateFunctionInvocation(
|
void visitAggregateFunctionInvocation(
|
||||||
AggregateFunctionInvocation e, void arg) {
|
AggregateFunctionInvocation e, void arg) {
|
||||||
|
@ -1321,7 +1325,7 @@ class NodeSqlBuilder extends AstVisitor<void, void> {
|
||||||
/// Writes an identifier, escaping it if necessary.
|
/// Writes an identifier, escaping it if necessary.
|
||||||
void identifier(String identifier,
|
void identifier(String identifier,
|
||||||
{bool spaceBefore = true, bool spaceAfter = true}) {
|
{bool spaceBefore = true, bool spaceAfter = true}) {
|
||||||
if (isKeywordLexeme(identifier) || _notAKeywordRegex.hasMatch(identifier)) {
|
if (isKeyword(identifier) || _notAKeywordRegex.hasMatch(identifier)) {
|
||||||
identifier = '"$identifier"';
|
identifier = '"$identifier"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: sqlparser
|
name: sqlparser
|
||||||
description: Parses sqlite statements and performs static analysis on them
|
description: Parses sqlite statements and performs static analysis on them
|
||||||
version: 0.27.0
|
version: 0.28.0-dev
|
||||||
homepage: https://github.com/simolus3/drift/tree/develop/sqlparser
|
homepage: https://github.com/simolus3/drift/tree/develop/sqlparser
|
||||||
repository: https://github.com/simolus3/drift
|
repository: https://github.com/simolus3/drift
|
||||||
#homepage: https://drift.simonbinder.eu/
|
#homepage: https://drift.simonbinder.eu/
|
||||||
|
|
Loading…
Reference in New Issue