sequel_core 2.2.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. metadata +30 -101
  2. data/CHANGELOG +0 -1519
  3. data/COPYING +0 -19
  4. data/README +0 -313
  5. data/Rakefile +0 -158
  6. data/bin/sequel +0 -117
  7. data/doc/cheat_sheet.rdoc +0 -225
  8. data/doc/dataset_filtering.rdoc +0 -182
  9. data/lib/sequel_core.rb +0 -136
  10. data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -68
  11. data/lib/sequel_core/adapters/ado.rb +0 -90
  12. data/lib/sequel_core/adapters/db2.rb +0 -160
  13. data/lib/sequel_core/adapters/dbi.rb +0 -127
  14. data/lib/sequel_core/adapters/informix.rb +0 -89
  15. data/lib/sequel_core/adapters/jdbc.rb +0 -110
  16. data/lib/sequel_core/adapters/mysql.rb +0 -486
  17. data/lib/sequel_core/adapters/odbc.rb +0 -167
  18. data/lib/sequel_core/adapters/odbc_mssql.rb +0 -106
  19. data/lib/sequel_core/adapters/openbase.rb +0 -76
  20. data/lib/sequel_core/adapters/oracle.rb +0 -182
  21. data/lib/sequel_core/adapters/postgres.rb +0 -560
  22. data/lib/sequel_core/adapters/sqlite.rb +0 -270
  23. data/lib/sequel_core/connection_pool.rb +0 -194
  24. data/lib/sequel_core/core_ext.rb +0 -197
  25. data/lib/sequel_core/core_sql.rb +0 -184
  26. data/lib/sequel_core/database.rb +0 -462
  27. data/lib/sequel_core/database/schema.rb +0 -156
  28. data/lib/sequel_core/dataset.rb +0 -457
  29. data/lib/sequel_core/dataset/callback.rb +0 -13
  30. data/lib/sequel_core/dataset/convenience.rb +0 -245
  31. data/lib/sequel_core/dataset/pagination.rb +0 -96
  32. data/lib/sequel_core/dataset/query.rb +0 -41
  33. data/lib/sequel_core/dataset/schema.rb +0 -15
  34. data/lib/sequel_core/dataset/sql.rb +0 -889
  35. data/lib/sequel_core/deprecated.rb +0 -26
  36. data/lib/sequel_core/exceptions.rb +0 -42
  37. data/lib/sequel_core/migration.rb +0 -187
  38. data/lib/sequel_core/object_graph.rb +0 -216
  39. data/lib/sequel_core/pretty_table.rb +0 -71
  40. data/lib/sequel_core/schema.rb +0 -2
  41. data/lib/sequel_core/schema/generator.rb +0 -239
  42. data/lib/sequel_core/schema/sql.rb +0 -326
  43. data/lib/sequel_core/sql.rb +0 -812
  44. data/lib/sequel_core/worker.rb +0 -68
  45. data/spec/adapters/informix_spec.rb +0 -96
  46. data/spec/adapters/mysql_spec.rb +0 -765
  47. data/spec/adapters/oracle_spec.rb +0 -222
  48. data/spec/adapters/postgres_spec.rb +0 -441
  49. data/spec/adapters/sqlite_spec.rb +0 -413
  50. data/spec/connection_pool_spec.rb +0 -363
  51. data/spec/core_ext_spec.rb +0 -156
  52. data/spec/core_sql_spec.rb +0 -427
  53. data/spec/database_spec.rb +0 -963
  54. data/spec/dataset_spec.rb +0 -2933
  55. data/spec/expression_filters_spec.rb +0 -316
  56. data/spec/migration_spec.rb +0 -261
  57. data/spec/object_graph_spec.rb +0 -230
  58. data/spec/pretty_table_spec.rb +0 -58
  59. data/spec/rcov.opts +0 -6
  60. data/spec/schema_generator_spec.rb +0 -122
  61. data/spec/schema_spec.rb +0 -422
  62. data/spec/spec.opts +0 -0
  63. data/spec/spec_config.rb +0 -7
  64. data/spec/spec_config.rb.example +0 -8
  65. data/spec/spec_helper.rb +0 -55
  66. data/spec/worker_spec.rb +0 -96
@@ -1,71 +0,0 @@
1
- module Sequel
2
- module PrettyTable
3
- # Prints nice-looking plain-text tables via puts
4
- #
5
- # +--+-------+
6
- # |id|name |
7
- # |--+-------|
8
- # |1 |fasdfas|
9
- # |2 |test |
10
- # +--+-------+
11
- def self.print(records, columns = nil) # records is an array of hashes
12
- columns ||= records.first.keys.sort_by{|x|x.to_s}
13
- sizes = column_sizes(records, columns)
14
- sep_line = separator_line(columns, sizes)
15
-
16
- puts sep_line
17
- puts header_line(columns, sizes)
18
- puts sep_line
19
- records.each {|r| puts data_line(columns, sizes, r)}
20
- puts sep_line
21
- end
22
-
23
- ### Private Module Methods ###
24
-
25
- # Hash of the maximum size of the value for each column
26
- def self.column_sizes(records, columns) # :nodoc:
27
- sizes = Hash.new {0}
28
- columns.each do |c|
29
- s = c.to_s.size
30
- sizes[c.to_sym] = s if s > sizes[c.to_sym]
31
- end
32
- records.each do |r|
33
- columns.each do |c|
34
- s = r[c].to_s.size
35
- sizes[c.to_sym] = s if s > sizes[c.to_sym]
36
- end
37
- end
38
- sizes
39
- end
40
-
41
- # String for each data line
42
- def self.data_line(columns, sizes, record) # :nodoc:
43
- '|' << columns.map {|c| format_cell(sizes[c], record[c])}.join('|') << '|'
44
- end
45
-
46
- # Format the value so it takes up exactly size characters
47
- def self.format_cell(size, v) # :nodoc:
48
- case v
49
- when Bignum, Fixnum
50
- "%#{size}d" % v
51
- when Float
52
- "%#{size}g" % v
53
- else
54
- "%-#{size}s" % v.to_s
55
- end
56
- end
57
-
58
- # String for header line
59
- def self.header_line(columns, sizes) # :nodoc:
60
- '|' << columns.map {|c| "%-#{sizes[c]}s" % c.to_s}.join('|') << '|'
61
- end
62
-
63
- # String for separtor line
64
- def self.separator_line(columns, sizes) # :nodoc:
65
- '+' << columns.map {|c| '-' * sizes[c]}.join('+') << '+'
66
- end
67
-
68
- private_class_method :column_sizes, :data_line, :format_cell, :header_line, :separator_line
69
- end
70
- end
71
-
@@ -1,2 +0,0 @@
1
- require 'sequel_core/schema/generator'
2
- require 'sequel_core/schema/sql'
@@ -1,239 +0,0 @@
1
- module Sequel
2
- # The Schema module holds the schema generators and the SQL code relating
3
- # to SQL DDL (Data Definition Language).
4
- module Schema
5
- # Schema::Generator is used to create tables. It takes a Database
6
- # object and a block of column/index/constraint specifications, and
7
- # creates a table in the database based on the specifications.
8
- #
9
- # Schema::Generator has some methods but also includes method_missing,
10
- # allowing users to specify column type as a method instead of using
11
- # the column method, which makes for a nicer DSL.
12
- #
13
- # See Database#create_table.
14
- class Generator
15
- # Set the database in which to create the table, and evaluate the block
16
- # in the context of this object.
17
- def initialize(db, &block)
18
- @db = db
19
- @columns = []
20
- @indexes = []
21
- @primary_key = nil
22
- instance_eval(&block) if block
23
- end
24
-
25
- # Add a unnamed constraint to the DDL, specified by the given block
26
- # or args.
27
- def check(*args, &block)
28
- constraint(nil, *args, &block)
29
- end
30
-
31
- # Add a column with the given name, type, and opts to the DDL.
32
- #
33
- # You can also create columns via method missing, so the following are
34
- # equivalent:
35
- #
36
- # column :number, :integer
37
- # integer :number
38
- #
39
- # The following options are supported:
40
- #
41
- # * :default - The default value for the column.
42
- # * :index - Create an index on this column.
43
- # * :key - For foreign key columns, the column in the associated table
44
- # that this column references. Unnecessary if this column
45
- # references the primary key of the associated table.
46
- # * :null - Mark the column as allowing NULL values (if true),
47
- # or not allowing NULL values (if false). If unspecified, will default
48
- # to whatever the database default is.
49
- # * :on_delete - Specify the behavior of this column when being deleted.
50
- # See Schema::SQL#on_delete_clause for options.
51
- # * :size - The size of the column, generally used with string
52
- # columns to specify the maximum number of characters the column will hold.
53
- # * :unique - Mark the column is unique, generally has the same effect as
54
- # creating a unique index on the column.
55
- # * :unsigned - Make the column type unsigned, only useful for integer
56
- # columns.
57
- def column(name, type, opts = {})
58
- @columns << {:name => name, :type => type}.merge(opts)
59
- index(name) if opts[:index]
60
- end
61
-
62
- # Adds a named constraint (or unnamed if name is nil) to the DDL,
63
- # with the given block or args.
64
- def constraint(name, *args, &block)
65
- @columns << {:name => name, :type => :check, :check => block || args}
66
- end
67
-
68
- # Return the DDL created by the generator as a array of two elements,
69
- # the first being the columns and the second being the indexes.
70
- def create_info
71
- @columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name)
72
- [@columns, @indexes]
73
- end
74
-
75
- # Add a foreign key in the table that references another table to the DDL. See column
76
- # for available options.
77
- def foreign_key(name, table=nil, opts = {})
78
- opts = case table
79
- when Hash
80
- table.merge(opts)
81
- when Symbol
82
- opts.merge(:table=>table)
83
- when NilClass
84
- opts
85
- else
86
- raise(Error, "The seconds argument to foreign_key should be a Hash, Symbol, or nil")
87
- end
88
- column(name, :integer, opts)
89
- end
90
-
91
- # Add a full text index on the given columns to the DDL.
92
- def full_text_index(columns, opts = {})
93
- index(columns, opts.merge(:type => :full_text))
94
- end
95
-
96
- # True if the DDL includes the creation of a column with the given name.
97
- def has_column?(name)
98
- @columns.any?{|c| c[:name] == name}
99
- end
100
-
101
- # Add an index on the given column(s) with the given options to the DDL.
102
- # The available options are:
103
- #
104
- # * :type - The type of index to use (only supported by some databases)
105
- # * :unique - Make the index unique, so duplicate values are not allowed.
106
- # * :where - Create a partial index (only supported by some databases)
107
- def index(columns, opts = {})
108
- @indexes << {:columns => Array(columns)}.merge(opts)
109
- end
110
-
111
- # Add a column with the given type, name, and opts to the DDL. See column for available
112
- # options.
113
- def method_missing(type, name = nil, opts = {})
114
- name ? column(name, type, opts) : super
115
- end
116
-
117
- # Add a column with the given name and primary key options to the DDL. You
118
- # can optionally provide a type argument and/or an options hash argument
119
- # to change the primary key options. See column for available options.
120
- def primary_key(name, *args)
121
- @primary_key = @db.serial_primary_key_options.merge({:name => name})
122
-
123
- if opts = args.pop
124
- opts = {:type => opts} unless opts.is_a?(Hash)
125
- if type = args.pop
126
- opts.merge!(:type => type)
127
- end
128
- @primary_key.merge!(opts)
129
- end
130
- @primary_key
131
- end
132
-
133
- # The name of the primary key for this table, if it has a primary key.
134
- def primary_key_name
135
- @primary_key[:name] if @primary_key
136
- end
137
-
138
- # Add a spatial index on the given columns to the DDL.
139
- def spatial_index(columns, opts = {})
140
- index(columns, opts.merge(:type => :spatial))
141
- end
142
-
143
- # Add a unique index on the given columns to the DDL.
144
- def unique(columns, opts = {})
145
- index(columns, opts.merge(:unique => true))
146
- end
147
- end
148
-
149
- # The Schema::AlterTableGenerator creates DDL operations on existing tables,
150
- # such as adding/removing/modifying columns/indexes/constraints.
151
- class AlterTableGenerator
152
- # An array of DDL operations to perform
153
- attr_reader :operations
154
-
155
- # Set the Database object to which to apply the DDL, and evaluate the
156
- # block in the context of this object.
157
- def initialize(db, &block)
158
- @db = db
159
- @operations = []
160
- instance_eval(&block) if block
161
- end
162
-
163
- # Add a column with the given name, type, and opts to the DDL for the table.
164
- # See Generator#column for the available options.
165
- def add_column(name, type, opts = {})
166
- @operations << {:op => :add_column, :name => name, :type => type}.merge(opts)
167
- end
168
-
169
- # Add a constraint with the given name and args to the DDL for the table.
170
- # See Generator#constraint.
171
- def add_constraint(name, *args, &block)
172
- @operations << {:op => :add_constraint, :name => name, :type => :check, \
173
- :check => block || args}
174
- end
175
-
176
- # Add a foreign key with the given name and referencing the given table
177
- # to the DDL for the table. See Generator#column for the available options.
178
- def add_foreign_key(name, table, opts = {})
179
- add_column(name, :integer, {:table=>table}.merge(opts))
180
- end
181
-
182
- # Add a full text index on the given columns to the DDL for the table.
183
- # See Generator#index for available options.
184
- def add_full_text_index(columns, opts = {})
185
- add_index(columns, {:type=>:full_text}.merge(opts))
186
- end
187
-
188
- # Add an index on the given columns to the DDL for the table. See
189
- # Generator#index for available options.
190
- def add_index(columns, opts = {})
191
- @operations << {:op => :add_index, :columns => Array(columns)}.merge(opts)
192
- end
193
-
194
- # Add a primary key to the DDL for the table. See Generator#column
195
- # for the available options.
196
- def add_primary_key(name, opts = {})
197
- opts = @db.serial_primary_key_options.merge(opts)
198
- add_column(name, opts.delete(:type), opts)
199
- end
200
-
201
- # Add a spatial index on the given columns to the DDL for the table.
202
- # See Generator#index for available options.
203
- def add_spatial_index(columns, opts = {})
204
- add_index(columns, {:type=>:spatial}.merge(opts))
205
- end
206
-
207
- # Remove a column from the DDL for the table.
208
- def drop_column(name)
209
- @operations << {:op => :drop_column, :name => name}
210
- end
211
-
212
- # Remove a constraint from the DDL for the table.
213
- def drop_constraint(name)
214
- @operations << {:op => :drop_constraint, :name => name}
215
- end
216
-
217
- # Remove an index from the DDL for the table.
218
- def drop_index(columns)
219
- @operations << {:op => :drop_index, :columns => Array(columns)}
220
- end
221
-
222
- # Modify a column's name in the DDL for the table.
223
- def rename_column(name, new_name, opts = {})
224
- @operations << {:op => :rename_column, :name => name, :new_name => new_name}.merge(opts)
225
- end
226
-
227
- # Modify a column's default value in the DDL for the table.
228
- def set_column_default(name, default)
229
- @operations << {:op => :set_column_default, :name => name, :default => default}
230
- end
231
-
232
- # Modify a column's type in the DDL for the table.
233
- def set_column_type(name, type)
234
- @operations << {:op => :set_column_type, :name => name, :type => type}
235
- end
236
- end
237
- end
238
- end
239
-
@@ -1,326 +0,0 @@
1
- module Sequel
2
- module Schema
3
- module SQL
4
- AUTOINCREMENT = 'AUTOINCREMENT'.freeze
5
- CASCADE = 'CASCADE'.freeze
6
- COMMA_SEPARATOR = ', '.freeze
7
- NO_ACTION = 'NO ACTION'.freeze
8
- NOT_NULL = ' NOT NULL'.freeze
9
- NULL = ' NULL'.freeze
10
- PRIMARY_KEY = ' PRIMARY KEY'.freeze
11
- RESTRICT = 'RESTRICT'.freeze
12
- SET_DEFAULT = 'SET DEFAULT'.freeze
13
- SET_NULL = 'SET NULL'.freeze
14
- TYPES = Hash.new {|h, k| k}
15
- TYPES[:double] = 'double precision'
16
- UNDERSCORE = '_'.freeze
17
- UNIQUE = ' UNIQUE'.freeze
18
- UNSIGNED = ' UNSIGNED'.freeze
19
-
20
- # The SQL to execute to modify the DDL for the given table name. op
21
- # should be one of the operations returned by the AlterTableGenerator.
22
- def alter_table_sql(table, op)
23
- quoted_table = quote_identifier(table)
24
- quoted_name = quote_identifier(op[:name]) if op[:name]
25
- case op[:op]
26
- when :add_column
27
- "ALTER TABLE #{quoted_table} ADD COLUMN #{column_definition_sql(op)}"
28
- when :drop_column
29
- "ALTER TABLE #{quoted_table} DROP COLUMN #{quoted_name}"
30
- when :rename_column
31
- "ALTER TABLE #{quoted_table} RENAME COLUMN #{quoted_name} TO #{quote_identifier(op[:new_name])}"
32
- when :set_column_type
33
- "ALTER TABLE #{quoted_table} ALTER COLUMN #{quoted_name} TYPE #{op[:type]}"
34
- when :set_column_default
35
- "ALTER TABLE #{quoted_table} ALTER COLUMN #{quoted_name} SET DEFAULT #{literal(op[:default])}"
36
- when :add_index
37
- index_definition_sql(table, op)
38
- when :drop_index
39
- "DROP INDEX #{default_index_name(table, op[:columns])}"
40
- when :add_constraint
41
- "ALTER TABLE #{quoted_table} ADD #{constraint_definition_sql(op)}"
42
- when :drop_constraint
43
- "ALTER TABLE #{quoted_table} DROP CONSTRAINT #{quoted_name}"
44
- else
45
- raise Error, "Unsupported ALTER TABLE operation"
46
- end
47
- end
48
-
49
- # Array of SQL DDL modification statements for the given table,
50
- # corresponding to the DDL changes specified by the operations.
51
- def alter_table_sql_list(table, operations)
52
- operations.map{|op| alter_table_sql(table, op)}
53
- end
54
-
55
- # The SQL string specify the autoincrement property, generally used by
56
- # primary keys.
57
- def auto_increment_sql
58
- AUTOINCREMENT
59
- end
60
-
61
- # SQL DDL fragment containing the column creation SQL for the given column.
62
- def column_definition_sql(column)
63
- return constraint_definition_sql(column) if column[:type] == :check
64
- sql = "#{quote_identifier(column[:name])} #{type_literal(TYPES[column[:type]])}"
65
- column[:size] ||= 255 if column[:type] == :varchar
66
- elements = column[:size] || column[:elements]
67
- sql << literal(Array(elements)) if elements
68
- sql << UNSIGNED if column[:unsigned]
69
- sql << UNIQUE if column[:unique]
70
- sql << NOT_NULL if column[:null] == false
71
- sql << NULL if column[:null] == true
72
- sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
73
- sql << PRIMARY_KEY if column[:primary_key]
74
- sql << " #{auto_increment_sql}" if column[:auto_increment]
75
- if column[:table]
76
- sql << " REFERENCES #{quote_identifier(column[:table])}"
77
- sql << "(#{quote_identifier(column[:key])})" if column[:key]
78
- sql << " ON DELETE #{on_delete_clause(column[:on_delete])}" if column[:on_delete]
79
- end
80
- sql
81
- end
82
-
83
- # SQL DDL fragment containing the column creation
84
- # SQL for all given columns, used instead a CREATE TABLE block.
85
- def column_list_sql(columns)
86
- columns.map{|c| column_definition_sql(c)}.join(COMMA_SEPARATOR)
87
- end
88
-
89
- # SQL DDL fragment specifying a constraint on a table.
90
- def constraint_definition_sql(constraint)
91
- sql = constraint[:name] ? "CONSTRAINT #{quote_identifier(constraint[:name])} " : ""
92
- sql << "CHECK #{filter_expr(constraint[:check])}"
93
- sql
94
- end
95
-
96
- # Array of SQL DDL statements, the first for creating a table with the given
97
- # name and column specifications, and the others for specifying indexes on
98
- # the table.
99
- def create_table_sql_list(name, columns, indexes = nil)
100
- sql = ["CREATE TABLE #{quote_identifier(name)} (#{column_list_sql(columns)})"]
101
- sql.concat(index_list_sql_list(name, indexes)) if indexes && !indexes.empty?
102
- sql
103
- end
104
-
105
- # Default index name for the table and columns, may be too long
106
- # for certain databases.
107
- def default_index_name(table_name, columns)
108
- "#{table_name}_#{columns.join(UNDERSCORE)}_index"
109
- end
110
-
111
- # SQL DDL statement to drop the table with the given name.
112
- def drop_table_sql(name)
113
- "DROP TABLE #{quote_identifier(name)}"
114
- end
115
-
116
- # Proxy the filter_expr call to the dataset, used for creating constraints.
117
- def filter_expr(*args, &block)
118
- schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
119
- end
120
-
121
- # SQL DDL statement for creating an index for the table with the given name
122
- # and index specifications.
123
- def index_definition_sql(table_name, index)
124
- index_name = index[:name] || default_index_name(table_name, index[:columns])
125
- if index[:type]
126
- raise Error, "Index types are not supported for this database"
127
- elsif index[:where]
128
- raise Error, "Partial indexes are not supported for this database"
129
- else
130
- "CREATE #{'UNIQUE ' if index[:unique]}INDEX #{index_name} ON #{quote_identifier(table_name)} #{literal(index[:columns])}"
131
- end
132
- end
133
-
134
- # Array of SQL DDL statements, one for each index specification,
135
- # for the given table.
136
- def index_list_sql_list(table_name, indexes)
137
- indexes.map{|i| index_definition_sql(table_name, i)}
138
- end
139
-
140
- # Proxy the literal call to the dataset, used for default values.
141
- def literal(v)
142
- schema_utility_dataset.literal(v)
143
- end
144
-
145
- # SQL DDL ON DELETE fragment to use, based on the given action.
146
- # The following actions are recognized:
147
- #
148
- # * :cascade - Delete rows referencing this row.
149
- # * :no_action (default) - Raise an error if other rows reference this
150
- # row, allow deferring of the integrity check.
151
- # * :restrict - Raise an error if other rows reference this row,
152
- # but do not allow deferring the integrity check.
153
- # * :set_default - Set columns referencing this row to their default value.
154
- # * :set_null - Set columns referencing this row to NULL.
155
- def on_delete_clause(action)
156
- case action
157
- when :restrict
158
- RESTRICT
159
- when :cascade
160
- CASCADE
161
- when :set_null
162
- SET_NULL
163
- when :set_default
164
- SET_DEFAULT
165
- else
166
- NO_ACTION
167
- end
168
- end
169
-
170
- # Proxy the quote_identifier method to the dataset, used for quoting tables and columns.
171
- def quote_identifier(v)
172
- schema_utility_dataset.quote_identifier(v)
173
- end
174
-
175
- # SQL DDL statement for renaming a table.
176
- def rename_table_sql(name, new_name)
177
- "ALTER TABLE #{quote_identifier(name)} RENAME TO #{quote_identifier(new_name)}"
178
- end
179
-
180
- # Parse the schema from the database using the SQL standard INFORMATION_SCHEMA.
181
- # If the table_name is not given, returns the schema for all tables as a hash.
182
- # If the table_name is given, returns the schema for a single table as an
183
- # array with all members being arrays of length 2. Available options are:
184
- #
185
- # * :reload - Get fresh information from the database, instead of using
186
- # cached information. If table_name is blank, :reload should be used
187
- # unless you are sure that schema has not been called before with a
188
- # table_name, otherwise you may only getting the schemas for tables
189
- # that have been requested explicitly.
190
- def schema(table_name = nil, opts={})
191
- if opts[:reload] && @schemas
192
- if table_name
193
- @schemas.delete(table_name)
194
- else
195
- @schemas = nil
196
- end
197
- end
198
-
199
- if table_name
200
- return @schemas[table_name] if @schemas && @schemas[table_name]
201
- else
202
- return @schemas if @schemas
203
- end
204
-
205
- if table_name
206
- @schemas ||= {}
207
- @schemas[table_name] ||= schema_parse_table(table_name, opts)
208
- else
209
- @schemas = schema_parse_tables(opts)
210
- end
211
- end
212
-
213
- # The dataset to use for proxying certain schema methods.
214
- def schema_utility_dataset
215
- @schema_utility_dataset ||= dataset
216
- end
217
-
218
- # SQL fragment specifying the type of a given column.
219
- def type_literal(t)
220
- t.is_a?(Symbol) ? t.to_s : literal(t)
221
- end
222
-
223
- private
224
-
225
- # Match the database's column type to a ruby type via a
226
- # regular expression. The following ruby types are supported:
227
- # integer, string, date, datetime, boolean, and float.
228
- def schema_column_type(db_type)
229
- case db_type
230
- when 'tinyint'
231
- Sequel.convert_tinyint_to_bool ? :boolean : :integer
232
- when /\A(int(eger)?|bigint|smallint)\z/
233
- :integer
234
- when /\A(character( varying)?|varchar|text)\z/
235
- :string
236
- when /\Adate\z/
237
- :date
238
- when /\A(datetime|timestamp( with(out)? time zone)?)\z/
239
- :datetime
240
- when /\Atime( with(out)? time zone)?\z/
241
- :time
242
- when "boolean"
243
- :boolean
244
- when /\A(real|float|double( precision)?)\z/
245
- :float
246
- when /\A(numeric|decimal|money)\z/
247
- :decimal
248
- when "bytea"
249
- :blob
250
- end
251
- end
252
-
253
- # The final dataset used by the schema parser, after all
254
- # options have been applied.
255
- def schema_ds(table_name, opts)
256
- schema_ds_dataset.from(*schema_ds_from(table_name, opts)) \
257
- .select(*schema_ds_select(table_name, opts)) \
258
- .join(*schema_ds_join(table_name, opts)) \
259
- .filter(*schema_ds_filter(table_name, opts))
260
- end
261
-
262
- # The blank dataset used by the schema parser.
263
- def schema_ds_dataset
264
- schema_utility_dataset
265
- end
266
-
267
- # Argument array for the schema dataset's filter method.
268
- def schema_ds_filter(table_name, opts)
269
- if table_name
270
- [{:c__table_name=>table_name.to_s}]
271
- else
272
- [{:t__table_type=>'BASE TABLE'}]
273
- end
274
- end
275
-
276
- # Argument array for the schema dataset's from method.
277
- def schema_ds_from(table_name, opts)
278
- [:information_schema__tables___t]
279
- end
280
-
281
- # Argument array for the schema dataset's join method.
282
- def schema_ds_join(table_name, opts)
283
- [:information_schema__columns, {:table_catalog=>:table_catalog,
284
- :table_schema => :table_schema, :table_name => :table_name} , :c]
285
- end
286
-
287
- # Argument array for the schema dataset's select method.
288
- def schema_ds_select(table_name, opts)
289
- cols = [:column_name___column, :data_type___db_type, :character_maximum_length___max_chars, \
290
- :numeric_precision, :column_default___default, :is_nullable___allow_null]
291
- cols << :c__table_name unless table_name
292
- cols
293
- end
294
-
295
- # Parse the schema for a given table.
296
- def schema_parse_table(table_name, opts)
297
- schema_parse_rows(schema_ds(table_name, opts))
298
- end
299
-
300
- # Parse the schema all tables in the database.
301
- def schema_parse_tables(opts)
302
- schemas = {}
303
- schema_ds(nil, opts).each do |row|
304
- (schemas[row.delete(:table_name).to_sym] ||= []) << row
305
- end
306
- schemas.each do |table, rows|
307
- schemas[table] = schema_parse_rows(rows)
308
- end
309
- schemas
310
- end
311
-
312
- # Parse the output of the information schema columns into
313
- # the hash used by Sequel.
314
- def schema_parse_rows(rows)
315
- schema = []
316
- rows.each do |row|
317
- row[:allow_null] = row[:allow_null] == 'YES' ? true : false
318
- row[:default] = nil if row[:default].blank?
319
- row[:type] = schema_column_type(row[:db_type])
320
- schema << [row.delete(:column).to_sym, row]
321
- end
322
- schema
323
- end
324
- end
325
- end
326
- end