166 lines
4 KiB
Dart
Executable file
166 lines
4 KiB
Dart
Executable file
import 'dart:collection';
|
|
import 'package:angel_orm/angel_orm.dart';
|
|
import 'package:angel_migration/angel_migration.dart';
|
|
import 'package:charcode/ascii.dart';
|
|
|
|
abstract class PostgresGenerator {
|
|
static String columnType(MigrationColumn column) {
|
|
var str = column.type.name;
|
|
if (column.length != null)
|
|
return '$str(${column.length})';
|
|
else
|
|
return str;
|
|
}
|
|
|
|
static String compileColumn(MigrationColumn column) {
|
|
var buf = new StringBuffer(columnType(column));
|
|
|
|
if (column.isNullable == false) buf.write(' NOT NULL');
|
|
if (column.defaultValue != null) {
|
|
String s;
|
|
var value = column.defaultValue;
|
|
if (value is RawSql)
|
|
s = value.value;
|
|
else if (value is String) {
|
|
var b = StringBuffer();
|
|
for (var ch in value.codeUnits) {
|
|
if (ch == $single_quote) {
|
|
b.write("\\'");
|
|
} else {
|
|
b.writeCharCode(ch);
|
|
}
|
|
}
|
|
s = b.toString();
|
|
} else {
|
|
s = value.toString();
|
|
}
|
|
|
|
buf.write(' DEFAULT $s');
|
|
}
|
|
|
|
if (column.indexType == IndexType.unique)
|
|
buf.write(' UNIQUE');
|
|
else if (column.indexType == IndexType.primaryKey)
|
|
buf.write(' PRIMARY KEY');
|
|
|
|
for (var ref in column.externalReferences) {
|
|
buf.write(' ' + compileReference(ref));
|
|
}
|
|
|
|
return buf.toString();
|
|
}
|
|
|
|
static String compileReference(MigrationColumnReference ref) {
|
|
var buf = new StringBuffer(
|
|
'REFERENCES "${ref.foreignTable}"("${ref.foreignKey}")');
|
|
if (ref.behavior != null) buf.write(' ' + ref.behavior);
|
|
return buf.toString();
|
|
}
|
|
}
|
|
|
|
class PostgresTable extends Table {
|
|
final Map<String, MigrationColumn> _columns = {};
|
|
|
|
@override
|
|
MigrationColumn declareColumn(String name, Column column) {
|
|
if (_columns.containsKey(name))
|
|
throw new StateError('Cannot redeclare column "$name".');
|
|
var col = new MigrationColumn.from(column);
|
|
_columns[name] = col;
|
|
return col;
|
|
}
|
|
|
|
void compile(StringBuffer buf, int indent) {
|
|
int i = 0;
|
|
|
|
_columns.forEach((name, column) {
|
|
var col = PostgresGenerator.compileColumn(column);
|
|
if (i++ > 0) buf.writeln(',');
|
|
|
|
for (int i = 0; i < indent; i++) {
|
|
buf.write(' ');
|
|
}
|
|
|
|
buf.write('"$name" $col');
|
|
});
|
|
}
|
|
}
|
|
|
|
class PostgresAlterTable extends Table implements MutableTable {
|
|
final Map<String, MigrationColumn> _columns = {};
|
|
final String tableName;
|
|
final Queue<String> _stack = new Queue<String>();
|
|
|
|
PostgresAlterTable(this.tableName);
|
|
|
|
void compile(StringBuffer buf, int indent) {
|
|
int i = 0;
|
|
|
|
while (_stack.isNotEmpty) {
|
|
var str = _stack.removeFirst();
|
|
|
|
if (i++ > 0) buf.writeln(',');
|
|
|
|
for (int i = 0; i < indent; i++) {
|
|
buf.write(' ');
|
|
}
|
|
|
|
buf.write(str);
|
|
}
|
|
|
|
if (i > 0) buf.writeln(';');
|
|
|
|
i = 0;
|
|
_columns.forEach((name, column) {
|
|
var col = PostgresGenerator.compileColumn(column);
|
|
if (i++ > 0) buf.writeln(',');
|
|
|
|
for (int i = 0; i < indent; i++) {
|
|
buf.write(' ');
|
|
}
|
|
|
|
buf.write('ADD COLUMN "$name" $col');
|
|
});
|
|
}
|
|
|
|
@override
|
|
MigrationColumn declareColumn(String name, Column column) {
|
|
if (_columns.containsKey(name))
|
|
throw new StateError('Cannot redeclare column "$name".');
|
|
var col = new MigrationColumn.from(column);
|
|
_columns[name] = col;
|
|
return col;
|
|
}
|
|
|
|
@override
|
|
void dropNotNull(String name) {
|
|
_stack.add('ALTER COLUMN "$name" DROP NOT NULL');
|
|
}
|
|
|
|
@override
|
|
void setNotNull(String name) {
|
|
_stack.add('ALTER COLUMN "$name" SET NOT NULL');
|
|
}
|
|
|
|
@override
|
|
void changeColumnType(String name, ColumnType type, {int length}) {
|
|
_stack.add('ALTER COLUMN "$name" TYPE ' +
|
|
PostgresGenerator.columnType(
|
|
new MigrationColumn(type, length: length)));
|
|
}
|
|
|
|
@override
|
|
void renameColumn(String name, String newName) {
|
|
_stack.add('RENAME COLUMN "$name" TO "$newName"');
|
|
}
|
|
|
|
@override
|
|
void dropColumn(String name) {
|
|
_stack.add('DROP COLUMN "$name"');
|
|
}
|
|
|
|
@override
|
|
void rename(String newName) {
|
|
_stack.add('RENAME TO "$newName"');
|
|
}
|
|
}
|