parseSqliteSelector function
Parses the table/query selector tail of a SQLite path (omp's
parseSqliteSelector). Throws StateError with omp's messages on
unsupported combinations.
Implementation
SqliteSelector parseSqliteSelector(String subPath, String queryString) {
final normalizedSubPath = subPath.replaceFirst(RegExp('^:+'), '').trim();
final params = Uri.splitQueryString(queryString);
final rawQuery = params['q'];
if (rawQuery != null) {
final otherKeys = params.keys.where((key) => key != 'q');
if (normalizedSubPath.isNotEmpty || otherKeys.isNotEmpty) {
throw StateError(
'SQLite raw queries cannot be combined with table selectors or '
'pagination',
);
}
if (rawQuery.trim().isEmpty) {
throw StateError("SQLite query parameter 'q' cannot be empty");
}
return SqliteRawSelector(rawQuery);
}
if (normalizedSubPath.isEmpty) {
if (params.isNotEmpty) {
throw StateError(
'SQLite query parameters require a table selector or q=SELECT...',
);
}
return const SqliteListSelector();
}
final separatorIndex = normalizedSubPath.indexOf(':');
final table = separatorIndex == -1
? normalizedSubPath
: normalizedSubPath.substring(0, separatorIndex);
final key = separatorIndex == -1
? null
: normalizedSubPath.substring(separatorIndex + 1);
if (table.isEmpty) {
throw StateError('SQLite selectors must include a table name');
}
if (key != null && key.isNotEmpty) {
if (params.isNotEmpty) {
throw StateError(
'SQLite row lookups cannot be combined with query parameters',
);
}
return SqliteRowSelector(table, key);
}
final where = _validateWhereClause(params['where']);
final orderParam = params['order']?.trim();
final order = orderParam == null || orderParam.isEmpty ? null : orderParam;
final hasQueryParams =
params.containsKey('limit') ||
params.containsKey('offset') ||
order != null ||
where != null;
if (hasQueryParams) {
const knownKeys = {'limit', 'offset', 'order', 'where'};
for (final keyName in params.keys) {
if (!knownKeys.contains(keyName)) {
throw StateError("Unsupported SQLite query parameter '$keyName'");
}
}
return SqliteQuerySelector(
table: table,
limit: _parseLimit(params['limit'], defaultSqliteQueryLimit),
offset: _parseOffset(params['offset']),
order: order,
where: where,
);
}
if (params.isNotEmpty) {
throw StateError(
"Unsupported SQLite query parameter '${params.keys.first}'",
);
}
return SqliteSchemaSelector(table);
}