| Module | Sequel::Schema::SQL |
| In: |
lib/sequel_core/adapters/shared/mysql.rb
lib/sequel_core/schema/sql.rb |
| AUTOINCREMENT | = | 'AUTOINCREMENT'.freeze |
| CASCADE | = | 'CASCADE'.freeze |
| COMMA_SEPARATOR | = | ', '.freeze |
| NO_ACTION | = | 'NO ACTION'.freeze |
| NOT_NULL | = | ' NOT NULL'.freeze |
| NULL | = | ' NULL'.freeze |
| PRIMARY_KEY | = | ' PRIMARY KEY'.freeze |
| RESTRICT | = | 'RESTRICT'.freeze |
| SET_DEFAULT | = | 'SET DEFAULT'.freeze |
| SET_NULL | = | 'SET NULL'.freeze |
| TYPES | = | Hash.new {|h, k| k} |
| UNDERSCORE | = | '_'.freeze |
| UNIQUE | = | ' UNIQUE'.freeze |
| UNSIGNED | = | ' UNSIGNED'.freeze |
| column_references_sql | -> | default_column_references_sql |
| Keep default column_references_sql for add_foreign_key support | ||
The SQL to execute to modify the DDL for the given table name. op should be one of the operations returned by the AlterTableGenerator.
# File lib/sequel_core/schema/sql.rb, line 26
26: def alter_table_sql(table, op)
27: quoted_name = quote_identifier(op[:name]) if op[:name]
28: alter_table_op = case op[:op]
29: when :add_column
30: "ADD COLUMN #{column_definition_sql(op)}"
31: when :drop_column
32: "DROP COLUMN #{quoted_name}"
33: when :rename_column
34: "RENAME COLUMN #{quoted_name} TO #{quote_identifier(op[:new_name])}"
35: when :set_column_type
36: "ALTER COLUMN #{quoted_name} TYPE #{type_literal(op)}"
37: when :set_column_default
38: "ALTER COLUMN #{quoted_name} SET DEFAULT #{literal(op[:default])}"
39: when :set_column_null
40: "ALTER COLUMN #{quoted_name} #{op[:null] ? 'DROP' : 'SET'} NOT NULL"
41: when :add_index
42: return index_definition_sql(table, op)
43: when :drop_index
44: return drop_index_sql(table, op)
45: when :add_constraint
46: "ADD #{constraint_definition_sql(op)}"
47: when :drop_constraint
48: "DROP CONSTRAINT #{quoted_name}"
49: else
50: raise Error, "Unsupported ALTER TABLE operation"
51: end
52: "ALTER TABLE #{quote_schema_table(table)} #{alter_table_op}"
53: end
SQL DDL fragment containing the column creation SQL for the given column.
# File lib/sequel_core/schema/sql.rb, line 68
68: def column_definition_sql(column)
69: return constraint_definition_sql(column) if column[:type] == :check
70: sql = "#{quote_identifier(column[:name])} #{type_literal(column)}"
71: sql << UNIQUE if column[:unique]
72: sql << NOT_NULL if column[:null] == false
73: sql << NULL if column[:null] == true
74: sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
75: sql << PRIMARY_KEY if column[:primary_key]
76: sql << " #{auto_increment_sql}" if column[:auto_increment]
77: sql << column_references_sql(column) if column[:table]
78: sql
79: end
SQL DDL fragment for column foreign key references
# File lib/sequel_core/schema/sql.rb, line 88
88: def column_references_sql(column)
89: sql = " REFERENCES #{quote_schema_table(column[:table])}"
90: sql << "(#{Array(column[:key]).map{|x| quote_identifier(x)}.join(COMMA_SEPARATOR)})" if column[:key]
91: sql << " ON DELETE #{on_delete_clause(column[:on_delete])}" if column[:on_delete]
92: sql << " ON UPDATE #{on_delete_clause(column[:on_update])}" if column[:on_update]
93: sql
94: end
SQL DDL fragment specifying a constraint on a table.
# File lib/sequel_core/schema/sql.rb, line 97
97: def constraint_definition_sql(constraint)
98: sql = constraint[:name] ? "CONSTRAINT #{quote_identifier(constraint[:name])} " : ""
99: case constraint[:constraint_type]
100: when :primary_key
101: sql << "PRIMARY KEY #{literal(constraint[:columns])}"
102: when :foreign_key
103: sql << "FOREIGN KEY #{literal(constraint[:columns])}"
104: sql << column_references_sql(constraint)
105: when :unique
106: sql << "UNIQUE #{literal(constraint[:columns])}"
107: else
108: check = constraint[:check]
109: sql << "CHECK #{filter_expr((check.is_a?(Array) && check.length == 1) ? check.first : check)}"
110: end
111: sql
112: end
Array of SQL DDL statements, the first for creating a table with the given name and column specifications, and the others for specifying indexes on the table.
# File lib/sequel_core/schema/sql.rb, line 117
117: def create_table_sql_list(name, columns, indexes = nil, options = {})
118: sql = ["CREATE TABLE #{quote_schema_table(name)} (#{column_list_sql(columns)})"]
119: sql.concat(index_list_sql_list(name, indexes)) if indexes && !indexes.empty?
120: sql
121: end
Default index name for the table and columns, may be too long for certain databases.
# File lib/sequel_core/schema/sql.rb, line 125
125: def default_index_name(table_name, columns)
126: schema, table = schema_and_table(table_name)
127: "#{"#{schema}_" if schema and schema != default_schema}#{table}_#{columns.join(UNDERSCORE)}_index"
128: end
Proxy the filter_expr call to the dataset, used for creating constraints.
# File lib/sequel_core/schema/sql.rb, line 141
141: def filter_expr(*args, &block)
142: schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
143: end
SQL DDL statement for creating an index for the table with the given name and index specifications.
# File lib/sequel_core/schema/sql.rb, line 147
147: def index_definition_sql(table_name, index)
148: index_name = index[:name] || default_index_name(table_name, index[:columns])
149: if index[:type]
150: raise Error, "Index types are not supported for this database"
151: elsif index[:where]
152: raise Error, "Partial indexes are not supported for this database"
153: else
154: "CREATE #{'UNIQUE ' if index[:unique]}INDEX #{quote_identifier(index_name)} ON #{quote_identifier(table_name)} #{literal(index[:columns])}"
155: end
156: end
SQL DDL ON DELETE fragment to use, based on the given action. The following actions are recognized:
# File lib/sequel_core/schema/sql.rb, line 179
179: def on_delete_clause(action)
180: case action
181: when :restrict
182: RESTRICT
183: when :cascade
184: CASCADE
185: when :set_null
186: SET_NULL
187: when :set_default
188: SET_DEFAULT
189: else
190: NO_ACTION
191: end
192: end
Proxy the quote_identifier method to the dataset, used for quoting tables and columns.
# File lib/sequel_core/schema/sql.rb, line 200
200: def quote_identifier(v)
201: schema_utility_dataset.quote_identifier(v)
202: end
Proxy the quote_schema_table method to the dataset
# File lib/sequel_core/schema/sql.rb, line 195
195: def quote_schema_table(table)
196: schema_utility_dataset.quote_schema_table(table)
197: end
Parse the schema from the database. If the table_name is not given, returns the schema for all tables as a hash. If the table_name is given, returns the schema for a single table as an array with all members being arrays of length 2. Available options are:
# File lib/sequel_core/schema/sql.rb, line 221
221: def schema(table = nil, opts={})
222: raise(Error, 'schema parsing is not implemented on this database') unless respond_to?(:schema_parse_table, true)
223:
224: if table
225: sch, table_name = schema_and_table(table)
226: quoted_name = quote_schema_table(table)
227: end
228: opts = opts.merge(:schema=>sch) if sch && !opts.include?(:schema)
229: if opts[:reload] && @schemas
230: if table_name
231: @schemas.delete(quoted_name)
232: else
233: @schemas = nil
234: end
235: end
236:
237: if @schemas
238: if table_name
239: return @schemas[quoted_name] if @schemas[quoted_name]
240: else
241: return @schemas
242: end
243: end
244:
245: raise(Error, '#tables does not exist, you must provide a specific table to #schema') if table.nil? && !respond_to?(:tables, true)
246:
247: @schemas ||= Hash.new do |h,k|
248: quote_name = quote_schema_table(k)
249: h[quote_name] if h.include?(quote_name)
250: end
251:
252: if table_name
253: cols = schema_parse_table(table_name, opts)
254: raise(Error, 'schema parsing returned no columns, table probably doesn\'t exist') if cols.blank?
255: @schemas[quoted_name] = cols
256: else
257: tables.each{|t| @schemas[quote_schema_table(t)] = schema_parse_table(t.to_s, opts)}
258: @schemas
259: end
260: end