1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#include "stdafx.h"
#include "Schema.h"
#include "Core/Join.h"
namespace sql {
Schema::Schema(Str *tableName, Array<Column *> *columns)
: tableName(tableName), columns(columns) {}
Schema::Schema(Str *tableName, Array<Column *> *columns, Array<Index *> *indices)
: tableName(tableName), columns(columns), index(indices) {}
Array<Schema::Index *> *Schema::indices() const {
if (index)
return index;
else
return new (this) Array<Index *>();
}
void Schema::toS(StrBuf *to) const {
*to << tableName << S(": {\n");
to->indent();
for (Nat i = 0; i < columns->count(); i++) {
*to << columns->at(i) << S("\n");
}
if (index) {
for (Nat i = 0; i < index->count(); i++) {
*to << index->at(i) << S("\n");
}
}
to->dedent();
*to << S("}");
}
void Schema::toSQL(QueryStrBuilder *to) const {
to->put(S("CREATE TABLE "));
to->name(tableName);
to->put(S(" ("));
Array<Str *> *pk = new (this) Array<Str *>();
for (Nat i = 0; i < columns->count(); i++) {
Column *col = columns->at(i);
if (col->attributes & primaryKey)
pk->push(col->name);
}
for (Nat i = 0; i < columns->count(); i++) {
if (i > 0)
to->put(S(", "));
Column *col = columns->at(i);
col->toSQL(to);
// We need to supply PK info here for implicit autoincrement to work on some databases (e.g. SQLite).
if (pk->count() == 1 && (col->attributes & primaryKey))
to->put(S(" PRIMARY KEY"));
}
// Multiple primary keys go at the end.
if (pk->count() > 1) {
to->put(S(", PRIMARY KEY("));
to->name(pk->at(0));
for (Nat i = 1; i < pk->count(); i++) {
to->put(S(", "));
to->name(pk->at(i));
}
to->put(S(")"));
}
to->put(S(")"));
}
Schema::Column::Column(Str *name, QueryType type)
: name(name), type(type), attributes(none) {}
Schema::Column::Column(Str *name, QueryType type, Attributes attrs)
: name(name), type(type), attributes(attrs) {}
void Schema::Column::toS(StrBuf *to) const {
*to << name << S(" ") << type;
sql::toSQL(to, attributes);
if (defaultValue)
*to << S(" DEFAULT ") << defaultValue;
if (unknown)
*to << S(" unknown: ") << unknown;
}
void Schema::Column::toSQL(QueryStrBuilder *to) const {
to->name(name);
to->put(S(" "));
to->type(type);
sql::toSQL(to, attributes & ~primaryKey);
if (defaultValue) {
to->put(S(" DEFAULT "));
to->put(defaultValue);
}
}
Schema::Index::Index(Str *name, Array<Str *> *columns)
: name(name), columns(columns) {}
void Schema::Index::toS(StrBuf *to) const {
*to << S("INDEX ON ") << name << S("(") << join(columns, S(", ")) << S(")");
}
void Schema::Index::toSQL(QueryStrBuilder *to, Str *table) const {
to->put(S("CREATE INDEX "));
to->name(name);
to->put(S(" ON "));
to->name(table);
to->put(S("("));
for (Nat i = 0; i < columns->count(); i++) {
if (i > 0)
to->put(S(", "));
to->name(columns->at(i));
}
to->put(S(")"));
}
void toSQL(QueryStrBuilder *to, Schema::Attributes attributes) {
if (attributes & Schema::primaryKey)
to->put(S(" PRIMARY KEY"));
if (attributes & Schema::notNull)
to->put(S(" NOT NULL"));
if (attributes & Schema::unique)
to->put(S(" UNIQUE"));
if (attributes & Schema::autoIncrement) {
to->put(S(" "));
to->autoIncrement();
}
}
void toSQL(StrBuf *to, Schema::Attributes attributes) {
if (attributes & Schema::primaryKey)
*to <<S (" PRIMARY KEY");
if (attributes & Schema::notNull)
*to << S(" NOT NULL");
if (attributes & Schema::unique)
*to << S(" UNIQUE");
if (attributes & Schema::autoIncrement)
*to << S(" AUTOINCREMENT");
}
Str *toSQL(EnginePtr e, Schema::Attributes attrs) {
StrBuf *out = new (e.v) StrBuf();
toSQL(out, attrs);
return out->toS();
}
}
|