sequel_core 2.2.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
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