sequel 2.11.0 → 2.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/CHANGELOG +168 -0
  2. data/README.rdoc +77 -95
  3. data/Rakefile +100 -80
  4. data/bin/sequel +2 -1
  5. data/doc/advanced_associations.rdoc +23 -32
  6. data/doc/cheat_sheet.rdoc +23 -40
  7. data/doc/dataset_filtering.rdoc +6 -6
  8. data/doc/prepared_statements.rdoc +22 -22
  9. data/doc/release_notes/2.12.0.txt +534 -0
  10. data/doc/schema.rdoc +3 -1
  11. data/doc/sharding.rdoc +8 -8
  12. data/doc/virtual_rows.rdoc +65 -0
  13. data/lib/sequel.rb +1 -1
  14. data/lib/{sequel_core → sequel}/adapters/ado.rb +3 -3
  15. data/lib/{sequel_core → sequel}/adapters/db2.rb +0 -0
  16. data/lib/{sequel_core → sequel}/adapters/dbi.rb +1 -1
  17. data/lib/{sequel_core → sequel}/adapters/do.rb +9 -5
  18. data/lib/{sequel_core → sequel}/adapters/do/mysql.rb +1 -1
  19. data/lib/{sequel_core → sequel}/adapters/do/postgres.rb +1 -1
  20. data/lib/{sequel_core → sequel}/adapters/do/sqlite.rb +1 -1
  21. data/lib/{sequel_core → sequel}/adapters/firebird.rb +84 -80
  22. data/lib/{sequel_core → sequel}/adapters/informix.rb +1 -1
  23. data/lib/{sequel_core → sequel}/adapters/jdbc.rb +21 -14
  24. data/lib/{sequel_core → sequel}/adapters/jdbc/h2.rb +14 -13
  25. data/lib/{sequel_core → sequel}/adapters/jdbc/mysql.rb +1 -1
  26. data/lib/{sequel_core → sequel}/adapters/jdbc/oracle.rb +1 -1
  27. data/lib/{sequel_core → sequel}/adapters/jdbc/postgresql.rb +1 -1
  28. data/lib/{sequel_core → sequel}/adapters/jdbc/sqlite.rb +1 -1
  29. data/lib/{sequel_core → sequel}/adapters/mysql.rb +60 -39
  30. data/lib/{sequel_core → sequel}/adapters/odbc.rb +8 -4
  31. data/lib/{sequel_core → sequel}/adapters/openbase.rb +0 -0
  32. data/lib/{sequel_core → sequel}/adapters/oracle.rb +38 -7
  33. data/lib/{sequel_core → sequel}/adapters/postgres.rb +24 -24
  34. data/lib/{sequel_core → sequel}/adapters/shared/mssql.rb +5 -5
  35. data/lib/{sequel_core → sequel}/adapters/shared/mysql.rb +126 -71
  36. data/lib/{sequel_core → sequel}/adapters/shared/oracle.rb +7 -10
  37. data/lib/{sequel_core → sequel}/adapters/shared/postgres.rb +159 -125
  38. data/lib/{sequel_core → sequel}/adapters/shared/progress.rb +1 -2
  39. data/lib/{sequel_core → sequel}/adapters/shared/sqlite.rb +72 -67
  40. data/lib/{sequel_core → sequel}/adapters/sqlite.rb +11 -7
  41. data/lib/{sequel_core → sequel}/adapters/utils/date_format.rb +0 -0
  42. data/lib/{sequel_core → sequel}/adapters/utils/stored_procedures.rb +0 -0
  43. data/lib/{sequel_core → sequel}/adapters/utils/unsupported.rb +19 -0
  44. data/lib/{sequel_core → sequel}/connection_pool.rb +7 -5
  45. data/lib/sequel/core.rb +221 -0
  46. data/lib/{sequel_core → sequel}/core_sql.rb +91 -49
  47. data/lib/{sequel_core → sequel}/database.rb +264 -149
  48. data/lib/{sequel_core/schema/generator.rb → sequel/database/schema_generator.rb} +6 -2
  49. data/lib/{sequel_core/database/schema.rb → sequel/database/schema_methods.rb} +12 -12
  50. data/lib/sequel/database/schema_sql.rb +224 -0
  51. data/lib/{sequel_core → sequel}/dataset.rb +78 -236
  52. data/lib/{sequel_core → sequel}/dataset/convenience.rb +99 -61
  53. data/lib/{sequel_core/object_graph.rb → sequel/dataset/graph.rb} +16 -14
  54. data/lib/{sequel_core → sequel}/dataset/prepared_statements.rb +1 -1
  55. data/lib/{sequel_core → sequel}/dataset/sql.rb +150 -99
  56. data/lib/sequel/deprecated.rb +593 -0
  57. data/lib/sequel/deprecated_migration.rb +91 -0
  58. data/lib/sequel/exceptions.rb +48 -0
  59. data/lib/sequel/extensions/blank.rb +42 -0
  60. data/lib/{sequel_model → sequel/extensions}/inflector.rb +8 -1
  61. data/lib/{sequel_core → sequel/extensions}/migration.rb +1 -1
  62. data/lib/{sequel_core/dataset → sequel/extensions}/pagination.rb +0 -0
  63. data/lib/{sequel_core → sequel/extensions}/pretty_table.rb +7 -0
  64. data/lib/{sequel_core/dataset → sequel/extensions}/query.rb +7 -0
  65. data/lib/sequel/extensions/string_date_time.rb +47 -0
  66. data/lib/sequel/metaprogramming.rb +43 -0
  67. data/lib/sequel/model.rb +110 -0
  68. data/lib/sequel/model/associations.rb +1300 -0
  69. data/lib/sequel/model/base.rb +937 -0
  70. data/lib/sequel/model/deprecated.rb +204 -0
  71. data/lib/sequel/model/deprecated_hooks.rb +103 -0
  72. data/lib/sequel/model/deprecated_inflector.rb +335 -0
  73. data/lib/sequel/model/deprecated_validations.rb +388 -0
  74. data/lib/sequel/model/errors.rb +39 -0
  75. data/lib/{sequel_model → sequel/model}/exceptions.rb +4 -4
  76. data/lib/sequel/model/inflections.rb +208 -0
  77. data/lib/sequel/model/plugins.rb +76 -0
  78. data/lib/sequel/plugins/caching.rb +122 -0
  79. data/lib/sequel/plugins/hook_class_methods.rb +122 -0
  80. data/lib/sequel/plugins/schema.rb +53 -0
  81. data/lib/sequel/plugins/serialization.rb +117 -0
  82. data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
  83. data/lib/sequel/plugins/validation_class_methods.rb +384 -0
  84. data/lib/sequel/plugins/validation_helpers.rb +150 -0
  85. data/lib/{sequel_core → sequel}/sql.rb +125 -190
  86. data/lib/{sequel_core → sequel}/version.rb +2 -1
  87. data/lib/sequel_core.rb +1 -172
  88. data/lib/sequel_model.rb +1 -91
  89. data/spec/adapters/firebird_spec.rb +5 -5
  90. data/spec/adapters/informix_spec.rb +1 -1
  91. data/spec/adapters/mysql_spec.rb +128 -42
  92. data/spec/adapters/oracle_spec.rb +47 -19
  93. data/spec/adapters/postgres_spec.rb +64 -52
  94. data/spec/adapters/spec_helper.rb +1 -1
  95. data/spec/adapters/sqlite_spec.rb +12 -17
  96. data/spec/{sequel_core → core}/connection_pool_spec.rb +10 -10
  97. data/spec/{sequel_core → core}/core_ext_spec.rb +19 -19
  98. data/spec/{sequel_core → core}/core_sql_spec.rb +68 -71
  99. data/spec/{sequel_core → core}/database_spec.rb +135 -99
  100. data/spec/{sequel_core → core}/dataset_spec.rb +398 -242
  101. data/spec/{sequel_core → core}/expression_filters_spec.rb +13 -13
  102. data/spec/core/migration_spec.rb +263 -0
  103. data/spec/{sequel_core → core}/object_graph_spec.rb +10 -10
  104. data/spec/{sequel_core → core}/pretty_table_spec.rb +2 -2
  105. data/spec/{sequel_core → core}/schema_generator_spec.rb +0 -0
  106. data/spec/{sequel_core → core}/schema_spec.rb +8 -10
  107. data/spec/{sequel_core → core}/spec_helper.rb +29 -2
  108. data/spec/{sequel_core → core}/version_spec.rb +0 -0
  109. data/spec/extensions/blank_spec.rb +67 -0
  110. data/spec/extensions/caching_spec.rb +201 -0
  111. data/spec/{sequel_model/hooks_spec.rb → extensions/hook_class_methods_spec.rb} +8 -23
  112. data/spec/{sequel_model → extensions}/inflector_spec.rb +3 -0
  113. data/spec/{sequel_core → extensions}/migration_spec.rb +4 -4
  114. data/spec/extensions/pagination_spec.rb +99 -0
  115. data/spec/extensions/pretty_table_spec.rb +91 -0
  116. data/spec/extensions/query_spec.rb +85 -0
  117. data/spec/{sequel_model → extensions}/schema_spec.rb +22 -1
  118. data/spec/extensions/serialization_spec.rb +109 -0
  119. data/spec/extensions/single_table_inheritance_spec.rb +53 -0
  120. data/spec/{sequel_model → extensions}/spec_helper.rb +13 -4
  121. data/spec/extensions/string_date_time_spec.rb +93 -0
  122. data/spec/{sequel_model/validations_spec.rb → extensions/validation_class_methods_spec.rb} +15 -103
  123. data/spec/extensions/validation_helpers_spec.rb +291 -0
  124. data/spec/integration/dataset_test.rb +31 -0
  125. data/spec/integration/eager_loader_test.rb +17 -30
  126. data/spec/integration/schema_test.rb +8 -5
  127. data/spec/integration/spec_helper.rb +17 -0
  128. data/spec/integration/transaction_test.rb +68 -0
  129. data/spec/{sequel_model → model}/association_reflection_spec.rb +0 -0
  130. data/spec/{sequel_model → model}/associations_spec.rb +23 -10
  131. data/spec/{sequel_model → model}/base_spec.rb +29 -20
  132. data/spec/{sequel_model → model}/caching_spec.rb +16 -14
  133. data/spec/{sequel_model → model}/dataset_methods_spec.rb +0 -0
  134. data/spec/{sequel_model → model}/eager_loading_spec.rb +8 -8
  135. data/spec/model/hooks_spec.rb +472 -0
  136. data/spec/model/inflector_spec.rb +126 -0
  137. data/spec/{sequel_model → model}/model_spec.rb +25 -20
  138. data/spec/model/plugins_spec.rb +142 -0
  139. data/spec/{sequel_model → model}/record_spec.rb +121 -62
  140. data/spec/model/schema_spec.rb +92 -0
  141. data/spec/model/spec_helper.rb +124 -0
  142. data/spec/model/validations_spec.rb +1080 -0
  143. metadata +136 -107
  144. data/lib/sequel_core/core_ext.rb +0 -217
  145. data/lib/sequel_core/dataset/callback.rb +0 -13
  146. data/lib/sequel_core/dataset/schema.rb +0 -15
  147. data/lib/sequel_core/deprecated.rb +0 -26
  148. data/lib/sequel_core/exceptions.rb +0 -44
  149. data/lib/sequel_core/schema.rb +0 -2
  150. data/lib/sequel_core/schema/sql.rb +0 -325
  151. data/lib/sequel_model/association_reflection.rb +0 -267
  152. data/lib/sequel_model/associations.rb +0 -499
  153. data/lib/sequel_model/base.rb +0 -539
  154. data/lib/sequel_model/caching.rb +0 -82
  155. data/lib/sequel_model/dataset_methods.rb +0 -26
  156. data/lib/sequel_model/eager_loading.rb +0 -370
  157. data/lib/sequel_model/hooks.rb +0 -101
  158. data/lib/sequel_model/plugins.rb +0 -62
  159. data/lib/sequel_model/record.rb +0 -568
  160. data/lib/sequel_model/schema.rb +0 -49
  161. data/lib/sequel_model/validations.rb +0 -429
  162. data/spec/sequel_model/plugins_spec.rb +0 -80
@@ -1,13 +0,0 @@
1
- module Sequel
2
- class Dataset
3
- private
4
- # This is run inside .all, after all
5
- # of the records have been loaded
6
- # via .each, but before any block passed
7
- # to all is called. It is called with
8
- # a single argument, an array of all
9
- # returned records.
10
- def post_load(all_records)
11
- end
12
- end
13
- end
@@ -1,15 +0,0 @@
1
- module Sequel
2
- class Dataset
3
- # Creates a view in the database with the given named based
4
- # on the current dataset.
5
- def create_view(name)
6
- @db.create_view(name, self)
7
- end
8
-
9
- # Creates or replaces a view in the database with the given
10
- # named based on the current dataset.
11
- def create_or_replace_view(name)
12
- @db.create_or_replace_view(name, self)
13
- end
14
- end
15
- end
@@ -1,26 +0,0 @@
1
- module Sequel
2
- # This module makes it easy to add deprecation functionality to other classes.
3
- module Deprecation # :nodoc:
4
- # This sets the output stream for the deprecation messages. Set it to an IO
5
- # (or any object that responds to puts) and it will call puts on that
6
- # object with the deprecation message. Set to nil to ignore deprecation messages.
7
- def self.deprecation_message_stream=(file)
8
- @dms = file
9
- end
10
-
11
- # Set this to true to print tracebacks with every deprecation message,
12
- # so you can see exactly where in your code the deprecated methods are
13
- # being called.
14
- def self.print_tracebacks=(pt)
15
- @pt = pt
16
- end
17
-
18
- # Puts the messages unaltered to the deprecation message stream
19
- def self.deprecate(message)
20
- if @dms
21
- @dms.puts(message)
22
- caller.each{|c| @dms.puts(c)} if @pt
23
- end
24
- end
25
- end
26
- end
@@ -1,44 +0,0 @@
1
- module Sequel
2
- # Represents an error raised in Sequel code.
3
- class Error < ::StandardError
4
-
5
- # Raised when Sequel is unable to load a specified adapter.
6
- class AdapterNotFound < Error ; end
7
-
8
- # Raised on an invalid operation.
9
- class InvalidOperation < Error; end
10
-
11
- # Error raised when an invalid statement is executed.
12
- class InvalidStatement < Error; end
13
-
14
- # Represents an Invalid transform.
15
- class InvalidTransform < Error ; end
16
-
17
- # Represents an invalid value stored in the database.
18
- class InvalidValue < Error ; end
19
-
20
- # Represents an attempt to performing filter operations when no filter has been specified yet.
21
- class NoExistingFilter < Error ; end
22
-
23
- # There was an error while waiting on a connection from the connection pool
24
- class PoolTimeoutError < Error ; end
25
-
26
- # Rollback is a special error used to rollback a transactions.
27
- # A transaction block will catch this error and won't pass further up the stack.
28
- class Rollback < Error ; end
29
- end
30
-
31
- # Generic error raised by the database adapters, indicating a
32
- # problem originating from the database server.
33
- class DatabaseError < Error; end
34
-
35
- # Error raised when the Sequel is unable to connect to the database with the
36
- # connection parameters it was given.
37
- class DatabaseConnectionError < DatabaseError; end
38
-
39
- # Error that should be raised by adapters when they determine that the connection
40
- # to the database has been lost. Instructs the connection pool code to
41
- # remove that connection from the pool so that other connections can be acquired
42
- # automatically.
43
- class DatabaseDisconnectError < DatabaseError; end
44
- end
@@ -1,2 +0,0 @@
1
- require 'sequel_core/schema/generator'
2
- require 'sequel_core/schema/sql'
@@ -1,325 +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.merge!(:double=>'double precision', String=>'varchar(255)',
16
- Integer=>'integer', Fixnum=>'integer', Bignum=>'bigint',
17
- Float=>'double precision', BigDecimal=>'numeric', Numeric=>'numeric',
18
- Date=>'date', DateTime=>'timestamp', Time=>'timestamp', File=>'blob',
19
- TrueClass=>'boolean', FalseClass=>'boolean')
20
- UNDERSCORE = '_'.freeze
21
- UNIQUE = ' UNIQUE'.freeze
22
- UNSIGNED = ' UNSIGNED'.freeze
23
-
24
- # The SQL to execute to modify the DDL for the given table name. op
25
- # should be one of the operations returned by the AlterTableGenerator.
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
54
-
55
- # Array of SQL DDL modification statements for the given table,
56
- # corresponding to the DDL changes specified by the operations.
57
- def alter_table_sql_list(table, operations)
58
- operations.map{|op| alter_table_sql(table, op)}
59
- end
60
-
61
- # The SQL string specify the autoincrement property, generally used by
62
- # primary keys.
63
- def auto_increment_sql
64
- AUTOINCREMENT
65
- end
66
-
67
- # SQL DDL fragment containing the column creation SQL for the given column.
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
80
-
81
- # SQL DDL fragment containing the column creation
82
- # SQL for all given columns, used instead a CREATE TABLE block.
83
- def column_list_sql(columns)
84
- columns.map{|c| column_definition_sql(c)}.join(COMMA_SEPARATOR)
85
- end
86
-
87
- # SQL DDL fragment for column foreign key references
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
95
-
96
- # SQL DDL fragment specifying a constraint on a table.
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
113
-
114
- # Array of SQL DDL statements, the first for creating a table with the given
115
- # name and column specifications, and the others for specifying indexes on
116
- # the table.
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
122
-
123
- # Default index name for the table and columns, may be too long
124
- # for certain databases.
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.map{|c| c.is_one_of?(String, Symbol) ? c : literal(c).gsub(/\W/, '_')}.join(UNDERSCORE)}_index"
128
- end
129
-
130
- # The SQL to drop an index for the table.
131
- def drop_index_sql(table, op)
132
- "DROP INDEX #{quote_identifier(op[:name] || default_index_name(table, op[:columns]))}"
133
- end
134
-
135
- # SQL DDL statement to drop the table with the given name.
136
- def drop_table_sql(name)
137
- "DROP TABLE #{quote_schema_table(name)}"
138
- end
139
-
140
- # Proxy the filter_expr call to the dataset, used for creating constraints.
141
- def filter_expr(*args, &block)
142
- schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
143
- end
144
-
145
- # SQL DDL statement for creating an index for the table with the given name
146
- # and index specifications.
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
157
-
158
- # Array of SQL DDL statements, one for each index specification,
159
- # for the given table.
160
- def index_list_sql_list(table_name, indexes)
161
- indexes.map{|i| index_definition_sql(table_name, i)}
162
- end
163
-
164
- # Proxy the literal call to the dataset, used for default values.
165
- def literal(v)
166
- schema_utility_dataset.literal(v)
167
- end
168
-
169
- # SQL DDL ON DELETE fragment to use, based on the given action.
170
- # The following actions are recognized:
171
- #
172
- # * :cascade - Delete rows referencing this row.
173
- # * :no_action (default) - Raise an error if other rows reference this
174
- # row, allow deferring of the integrity check.
175
- # * :restrict - Raise an error if other rows reference this row,
176
- # but do not allow deferring the integrity check.
177
- # * :set_default - Set columns referencing this row to their default value.
178
- # * :set_null - Set columns referencing this row to NULL.
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
193
-
194
- # Proxy the quote_schema_table method to the dataset
195
- def quote_schema_table(table)
196
- schema_utility_dataset.quote_schema_table(table)
197
- end
198
-
199
- # Proxy the quote_identifier method to the dataset, used for quoting tables and columns.
200
- def quote_identifier(v)
201
- schema_utility_dataset.quote_identifier(v)
202
- end
203
-
204
- # SQL DDL statement for renaming a table.
205
- def rename_table_sql(name, new_name)
206
- "ALTER TABLE #{quote_schema_table(name)} RENAME TO #{quote_schema_table(new_name)}"
207
- end
208
-
209
- # Parse the schema from the database.
210
- # If the table_name is not given, returns the schema for all tables as a hash.
211
- # If the table_name is given, returns the schema for a single table as an
212
- # array with all members being arrays of length 2. Available options are:
213
- #
214
- # * :reload - Get fresh information from the database, instead of using
215
- # cached information. If table_name is blank, :reload should be used
216
- # unless you are sure that schema has not been called before with a
217
- # table_name, otherwise you may only getting the schemas for tables
218
- # that have been requested explicitly.
219
- # * :schema - An explicit schema to use. It may also be implicitly provided
220
- # via the table name.
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
261
-
262
- # The dataset to use for proxying certain schema methods.
263
- def schema_utility_dataset
264
- @schema_utility_dataset ||= dataset
265
- end
266
-
267
- private
268
-
269
- # Remove the cached schema for the given schema name
270
- def remove_cached_schema(table)
271
- @schemas.delete(quote_schema_table(table)) if @schemas
272
- end
273
-
274
- # Remove the cached schema_utility_dataset, because the identifier
275
- # quoting has changed.
276
- def reset_schema_utility_dataset
277
- @schema_utility_dataset = nil
278
- end
279
-
280
- # Match the database's column type to a ruby type via a
281
- # regular expression. The following ruby types are supported:
282
- # integer, string, date, datetime, boolean, and float.
283
- def schema_column_type(db_type)
284
- case db_type
285
- when /\Atinyint/io
286
- Sequel.convert_tinyint_to_bool ? :boolean : :integer
287
- when /\Ainterval\z/io
288
- :interval
289
- when /\A(character( varying)?|varchar|text)/io
290
- :string
291
- when /\A(int(eger)?|bigint|smallint)/io
292
- :integer
293
- when /\Adate\z/io
294
- :date
295
- when /\A(datetime|timestamp( with(out)? time zone)?)\z/io
296
- :datetime
297
- when /\Atime( with(out)? time zone)?\z/io
298
- :time
299
- when /\Aboolean\z/io
300
- :boolean
301
- when /\A(real|float|double( precision)?)\z/io
302
- :float
303
- when /\A(numeric(\(\d+,\d+\))?|decimal|money)\z/io
304
- :decimal
305
- when /\Abytea\z/io
306
- :blob
307
- end
308
- end
309
-
310
- # SQL fragment specifying the type of a given column.
311
- def type_literal(column)
312
- type = type_literal_base(column)
313
- column[:size] ||= 255 if type.to_s == 'varchar'
314
- elements = column[:size] || column[:elements]
315
- "#{type}#{literal(Array(elements)) if elements}#{UNSIGNED if column[:unsigned]}"
316
- end
317
-
318
- # SQL fragment specifying the base type of a given column,
319
- # without the size or elements.
320
- def type_literal_base(column)
321
- TYPES[column[:type]]
322
- end
323
- end
324
- end
325
- end
@@ -1,267 +0,0 @@
1
- module Sequel::Model::Associations
2
- # Map of association type symbols to association reflection classes.
3
- ASSOCIATION_TYPES = {}
4
-
5
- # AssociationReflection is a Hash subclass that keeps information on Sequel::Model associations. It
6
- # provides methods to reduce internal code duplication. It should not
7
- # be instantiated by the user.
8
- class AssociationReflection < Hash
9
- # Name symbol for _add_ internal association method
10
- def _add_method
11
- :"_add_#{self[:name].to_s.singularize}"
12
- end
13
-
14
- # Name symbol for _dataset association method
15
- def _dataset_method
16
- :"_#{self[:name]}_dataset"
17
- end
18
-
19
- # Name symbol for _remove_all internal association method
20
- def _remove_all_method
21
- :"_remove_all_#{self[:name]}"
22
- end
23
-
24
- # Name symbol for _remove_ internal association method
25
- def _remove_method
26
- :"_remove_#{self[:name].to_s.singularize}"
27
- end
28
-
29
- # Name symbol for setter association method
30
- def _setter_method
31
- :"_#{self[:name]}="
32
- end
33
-
34
- # Name symbol for add_ association method
35
- def add_method
36
- :"add_#{self[:name].to_s.singularize}"
37
- end
38
-
39
- # Name symbol for association method, the same as the name of the association.
40
- def association_method
41
- self[:name]
42
- end
43
-
44
- # The class associated to the current model class via this association
45
- def associated_class
46
- self[:class] ||= self[:class_name].constantize
47
- end
48
-
49
- # Name symbol for dataset association method
50
- def dataset_method
51
- :"#{self[:name]}_dataset"
52
- end
53
-
54
- # Name symbol for _helper internal association method
55
- def dataset_helper_method
56
- :"_#{self[:name]}_dataset_helper"
57
- end
58
-
59
- # Whether the dataset needs a primary key to function, true by default.
60
- def dataset_need_primary_key?
61
- true
62
- end
63
-
64
- # Whether to eagerly graph a lazy dataset, true by default.
65
- def eager_graph_lazy_dataset?
66
- true
67
- end
68
-
69
- # Whether the associated object needs a primary key to be added/removed,
70
- # false by default.
71
- def need_associated_primary_key?
72
- false
73
- end
74
-
75
- # Returns/sets the reciprocal association variable, if one exists
76
- def reciprocal
77
- return self[:reciprocal] if include?(:reciprocal)
78
- r_type = reciprocal_type
79
- key = self[:key]
80
- associated_class.all_association_reflections.each do |assoc_reflect|
81
- if assoc_reflect[:type] == r_type && assoc_reflect[:key] == key
82
- return self[:reciprocal] = assoc_reflect[:name]
83
- end
84
- end
85
- self[:reciprocal] = nil
86
- end
87
-
88
- # Whether the reciprocal of this association returns an array of objects instead of a single object,
89
- # true by default.
90
- def reciprocal_array?
91
- true
92
- end
93
-
94
- # Name symbol for remove_all_ association method
95
- def remove_all_method
96
- :"remove_all_#{self[:name]}"
97
- end
98
-
99
- # Name symbol for remove_ association method
100
- def remove_method
101
- :"remove_#{self[:name].to_s.singularize}"
102
- end
103
-
104
- # Whether this association returns an array of objects instead of a single object,
105
- # true by default.
106
- def returns_array?
107
- true
108
- end
109
-
110
- # The columns to select when loading the association, nil by default.
111
- def select
112
- self[:select]
113
- end
114
-
115
- # By default, associations shouldn't set the reciprocal association to self.
116
- def set_reciprocal_to_self?
117
- false
118
- end
119
-
120
- # Name symbol for setter association method
121
- def setter_method
122
- :"#{self[:name]}="
123
- end
124
-
125
- end
126
-
127
- class ManyToOneAssociationReflection < AssociationReflection
128
- ASSOCIATION_TYPES[:many_to_one] = self
129
-
130
- # Whether the dataset needs a primary key to function, false for many_to_one associations.
131
- def dataset_need_primary_key?
132
- false
133
- end
134
-
135
- # Default foreign key name symbol for foreign key in current model's table that points to
136
- # the given association's table's primary key.
137
- def default_key
138
- :"#{self[:name]}_id"
139
- end
140
-
141
- # Whether to eagerly graph a lazy dataset, true for many_to_one associations
142
- # only if the key is nil.
143
- def eager_graph_lazy_dataset?
144
- self[:key].nil?
145
- end
146
-
147
- # The key to use for the key hash when eager loading
148
- def eager_loader_key
149
- self[:key]
150
- end
151
-
152
- # The column in the associated table that the key in the current table references.
153
- def primary_key
154
- self[:primary_key] ||= associated_class.primary_key
155
- end
156
-
157
- # Whether this association returns an array of objects instead of a single object,
158
- # false for a many_to_one association.
159
- def returns_array?
160
- false
161
- end
162
-
163
- private
164
-
165
- # The reciprocal type of a many_to_one association is a one_to_many association.
166
- def reciprocal_type
167
- :one_to_many
168
- end
169
- end
170
-
171
- class OneToManyAssociationReflection < AssociationReflection
172
- ASSOCIATION_TYPES[:one_to_many] = self
173
-
174
- # Default foreign key name symbol for key in associated table that points to
175
- # current table's primary key.
176
- def default_key
177
- :"#{self[:model].name.to_s.demodulize.underscore}_id"
178
- end
179
-
180
- # The key to use for the key hash when eager loading
181
- def eager_loader_key
182
- primary_key
183
- end
184
-
185
- # The column in the current table that the key in the associated table references.
186
- def primary_key
187
- self[:primary_key] ||= self[:model].primary_key
188
- end
189
-
190
- # One to many associations set the reciprocal to self.
191
- def set_reciprocal_to_self?
192
- true
193
- end
194
-
195
- # Whether the reciprocal of this association returns an array of objects instead of a single object,
196
- # false for a one_to_many association.
197
- def reciprocal_array?
198
- false
199
- end
200
-
201
- private
202
-
203
- # The reciprocal type of a one_to_many association is a many_to_one association.
204
- def reciprocal_type
205
- :many_to_one
206
- end
207
- end
208
-
209
- class ManyToManyAssociationReflection < AssociationReflection
210
- ASSOCIATION_TYPES[:many_to_many] = self
211
-
212
- # Default name symbol for the join table.
213
- def default_join_table
214
- ([self[:class_name].demodulize, self[:model].name.to_s.demodulize]. \
215
- map{|i| i.pluralize.underscore}.sort.join('_')).to_sym
216
- end
217
-
218
- # Default foreign key name symbol for key in join table that points to
219
- # current table's primary key (or :left_primary_key column).
220
- def default_left_key
221
- :"#{self[:model].name.to_s.demodulize.underscore}_id"
222
- end
223
-
224
- # Default foreign key name symbol for foreign key in join table that points to
225
- # the association's table's primary key (or :right_primary_key column).
226
- def default_right_key
227
- :"#{self[:name].to_s.singularize}_id"
228
- end
229
-
230
- # The key to use for the key hash when eager loading
231
- def eager_loader_key
232
- self[:left_primary_key]
233
- end
234
-
235
- # Whether the associated object needs a primary key to be added/removed,
236
- # true for many_to_many associations.
237
- def need_associated_primary_key?
238
- true
239
- end
240
-
241
- # Returns/sets the reciprocal association variable, if one exists
242
- def reciprocal
243
- return self[:reciprocal] if include?(:reciprocal)
244
- left_key = self[:left_key]
245
- right_key = self[:right_key]
246
- join_table = self[:join_table]
247
- associated_class.all_association_reflections.each do |assoc_reflect|
248
- if assoc_reflect[:type] == :many_to_many && assoc_reflect[:left_key] == right_key \
249
- && assoc_reflect[:right_key] == left_key && assoc_reflect[:join_table] == join_table
250
- return self[:reciprocal] = assoc_reflect[:name]
251
- end
252
- end
253
- self[:reciprocal] = nil
254
- end
255
-
256
- # The primary key column to use in the associated table.
257
- def right_primary_key
258
- self[:right_primary_key] ||= associated_class.primary_key
259
- end
260
-
261
- # The columns to select when loading the association, associated_class.table_name.* by default.
262
- def select
263
- return self[:select] if include?(:select)
264
- self[:select] ||= associated_class.table_name.*
265
- end
266
- end
267
- end