compileWheres method
Compile the "where" portion of the query.
Implementation
String compileWheres(List<Map<String, dynamic>> wheres) {
if (wheres.isEmpty) return '';
final lines = <String>[];
for (final where in wheres) {
final type = where['type'] as String;
final boolean = where['boolean'] as String;
String sql;
switch (type) {
case 'Raw':
sql = where['sql'];
break;
case 'Basic':
sql = '${wrap(where['column'])} ${where['operator']} ?';
break;
case 'In':
final values = where['values'] as List;
if (values.isEmpty) {
sql = '0 = 1';
} else {
final placeholders = List.filled(values.length, '?').join(', ');
sql = '${wrap(where['column'])} IN ($placeholders)';
}
break;
case 'NotIn':
final values = where['values'] as List;
if (values.isEmpty) {
sql = '1 = 1';
} else {
final placeholders = List.filled(values.length, '?').join(', ');
sql = '${wrap(where['column'])} NOT IN ($placeholders)';
}
break;
case 'Null':
sql = '${wrap(where['column'])} IS NULL';
break;
case 'NotNull':
sql = '${wrap(where['column'])} IS NOT NULL';
break;
case 'Between':
sql = '${wrap(where['column'])} BETWEEN ? AND ?';
break;
case 'NotBetween':
sql = '${wrap(where['column'])} NOT BETWEEN ? AND ?';
break;
case 'Date':
sql = 'DATE(${wrap(where['column'])}) ${where['operator']} ?';
break;
case 'Time':
sql = 'TIME(${wrap(where['column'])}) ${where['operator']} ?';
break;
case 'Year':
sql = 'YEAR(${wrap(where['column'])}) ${where['operator']} ?';
break;
case 'Month':
sql = 'MONTH(${wrap(where['column'])}) ${where['operator']} ?';
break;
case 'Day':
sql = 'DAY(${wrap(where['column'])}) ${where['operator']} ?';
break;
case 'Column':
sql =
'${wrap(where['first'])} ${where['operator']} ${wrap(where['second'])}';
break;
case 'Nested':
final nestedQuery = where['query'];
final nestedWheres =
(nestedQuery as dynamic).wheres as List<Map<String, dynamic>>;
final nestedSql = compileWheres(nestedWheres);
if (nestedSql.isEmpty) continue;
// Remove leading WHERE and boolean if present (AND/OR)
var cleanSql = nestedSql.replaceFirst('WHERE ', '');
cleanSql = cleanSql.replaceFirst(RegExp(r'^(AND|OR)\s+'), '');
sql = '($cleanSql)';
break;
case 'InSub':
final subquery = (where['query'] as dynamic).toSql();
sql = '${wrap(where['column'])} IN ($subquery)';
break;
case 'Exists':
final subquery = (where['query'] as dynamic).toSql();
sql = 'EXISTS ($subquery)';
break;
case 'NotExists':
final subquery = (where['query'] as dynamic).toSql();
sql = 'NOT EXISTS ($subquery)';
break;
case 'FullText':
final columns =
(where['columns'] as List<String>).map(wrap).join(', ');
final mode = where['mode'] == 'boolean'
? 'IN BOOLEAN MODE'
: where['mode'] == 'query_expansion' ||
where['mode'] == 'expansion'
? 'WITH QUERY EXPANSION'
: 'IN NATURAL LANGUAGE MODE';
sql = 'MATCH ($columns) AGAINST (? $mode)';
break;
case 'BetweenColumns':
sql =
'${wrap(where['column'])} BETWEEN ${wrap(where['start'])} AND ${wrap(where['end'])}';
break;
case 'NotBetweenColumns':
sql =
'${wrap(where['column'])} NOT BETWEEN ${wrap(where['start'])} AND ${wrap(where['end'])}';
break;
case 'JsonContains':
final path = where['path'] != null ? ', ?' : '';
sql = 'JSON_CONTAINS(${wrap(where['column'])}, ?$path)';
break;
case 'JsonContainsKey':
sql = 'JSON_CONTAINS_PATH(${wrap(where['column'])}, \'one\', ?)';
break;
case 'JsonDoesntContain':
final path = where['path'] != null ? ', ?' : '';
sql = 'NOT JSON_CONTAINS(${wrap(where['column'])}, ?$path)';
break;
case 'JsonLength':
final path = where['path'] != null ? ', ?' : '';
sql =
'JSON_LENGTH(${wrap(where['column'])}$path) ${where['operator']} ?';
break;
default:
continue;
}
if (lines.isNotEmpty) {
sql = '$boolean $sql';
}
lines.add(sql);
}
if (lines.isEmpty) return '';
return 'WHERE ${lines.join(' ')}';
}