buildUpsertSql<T> static method
SqlStatement
buildUpsertSql<T>(
- List<
TetherModel< models,T> > - String originalSupabaseTableName, {
- required Map<
String, SupabaseTableInfo> tableSchemas,
Generates a structured UPSERT statement for a list of models.
Implementation
static SqlStatement buildUpsertSql<T>(
List<TetherModel<T>> models,
String originalSupabaseTableName, {
required Map<String, SupabaseTableInfo> tableSchemas,
}) {
if (models.isEmpty) {
throw ArgumentError(
'Cannot build UPSERT statement from empty model list.',
);
}
final schemaKey = originalSupabaseTableName.contains('.')
? originalSupabaseTableName
: 'public.$originalSupabaseTableName';
final tableInfo = tableSchemas[schemaKey];
if (tableInfo == null) {
throw Exception(
"Schema information for table '$schemaKey' not found. Cannot build upsert SQL.",
);
}
final localTableName = tableInfo.localName;
final pkInfos = tableInfo.primaryKeys;
if (pkInfos.isEmpty) {
throw ArgumentError(
"Cannot build UPSERT: No primary keys defined for table '$schemaKey'. Conflict target is required.",
);
}
final pkLocalNames = pkInfos.map((pk) => pk.localName).toList();
final conflictTarget = pkLocalNames.join(', ');
final firstModelMap = models.first.toSqlite();
if (firstModelMap.isEmpty) {
throw ArgumentError('Cannot build UPSERT: First model has no data.');
}
final columns = firstModelMap.keys.toList();
final columnCount = columns.length;
final valuePlaceholderGroup =
'(${List.filled(columnCount, '?').join(', ')})';
final allPlaceholders = List.filled(
models.length,
valuePlaceholderGroup,
).join(', ');
final allArguments = <Object?>[];
final updateColumns =
columns.where((key) => !pkLocalNames.contains(key)).toList();
final updateSetClauses =
updateColumns.map((key) => '$key = excluded.$key').join(', ');
for (final model in models) {
final map = model.toSqlite();
if (map.length != columnCount ||
map.keys.join(',') != columns.join(',')) {
throw ArgumentError(
'Inconsistent model structure detected for bulk UPSERT.',
);
}
allArguments.addAll(map.values);
}
return SqlStatement(
operationType: SqlOperationType.upsert,
tableName: localTableName,
insertColumns: columns,
insertValuesPlaceholders: allPlaceholders,
insertArguments: allArguments,
upsertConflictTarget: conflictTarget,
upsertUpdateSetClauses:
updateSetClauses.isNotEmpty ? updateSetClauses : null,
);
}