sequel 3.47.0 → 3.48.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +230 -0
  3. data/README.rdoc +31 -40
  4. data/Rakefile +1 -14
  5. data/doc/active_record.rdoc +29 -29
  6. data/doc/association_basics.rdoc +4 -13
  7. data/doc/cheat_sheet.rdoc +8 -6
  8. data/doc/code_order.rdoc +89 -0
  9. data/doc/core_extensions.rdoc +3 -3
  10. data/doc/dataset_basics.rdoc +7 -8
  11. data/doc/dataset_filtering.rdoc +7 -2
  12. data/doc/mass_assignment.rdoc +2 -3
  13. data/doc/migration.rdoc +8 -8
  14. data/doc/model_hooks.rdoc +11 -7
  15. data/doc/object_model.rdoc +2 -2
  16. data/doc/opening_databases.rdoc +5 -14
  17. data/doc/prepared_statements.rdoc +5 -9
  18. data/doc/querying.rdoc +23 -28
  19. data/doc/reflection.rdoc +11 -0
  20. data/doc/release_notes/3.48.0.txt +477 -0
  21. data/doc/schema_modification.rdoc +12 -5
  22. data/doc/security.rdoc +2 -2
  23. data/doc/sharding.rdoc +1 -2
  24. data/doc/sql.rdoc +10 -13
  25. data/doc/testing.rdoc +8 -4
  26. data/doc/transactions.rdoc +2 -2
  27. data/doc/validations.rdoc +40 -17
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado.rb +25 -20
  30. data/lib/sequel/adapters/ado/access.rb +1 -0
  31. data/lib/sequel/adapters/ado/mssql.rb +1 -0
  32. data/lib/sequel/adapters/db2.rb +9 -7
  33. data/lib/sequel/adapters/dbi.rb +16 -16
  34. data/lib/sequel/adapters/do.rb +17 -18
  35. data/lib/sequel/adapters/do/mysql.rb +1 -0
  36. data/lib/sequel/adapters/do/postgres.rb +2 -0
  37. data/lib/sequel/adapters/do/sqlite.rb +1 -0
  38. data/lib/sequel/adapters/firebird.rb +5 -7
  39. data/lib/sequel/adapters/ibmdb.rb +23 -20
  40. data/lib/sequel/adapters/informix.rb +8 -2
  41. data/lib/sequel/adapters/jdbc.rb +39 -35
  42. data/lib/sequel/adapters/jdbc/as400.rb +1 -0
  43. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
  44. data/lib/sequel/adapters/jdbc/db2.rb +1 -0
  45. data/lib/sequel/adapters/jdbc/derby.rb +1 -0
  46. data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
  47. data/lib/sequel/adapters/jdbc/h2.rb +1 -0
  48. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
  49. data/lib/sequel/adapters/jdbc/informix.rb +1 -0
  50. data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
  51. data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
  52. data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
  53. data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
  54. data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
  55. data/lib/sequel/adapters/jdbc/progress.rb +1 -0
  56. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
  57. data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
  58. data/lib/sequel/adapters/mock.rb +30 -31
  59. data/lib/sequel/adapters/mysql.rb +6 -7
  60. data/lib/sequel/adapters/mysql2.rb +5 -6
  61. data/lib/sequel/adapters/odbc.rb +22 -20
  62. data/lib/sequel/adapters/odbc/mssql.rb +1 -0
  63. data/lib/sequel/adapters/openbase.rb +4 -1
  64. data/lib/sequel/adapters/oracle.rb +10 -8
  65. data/lib/sequel/adapters/postgres.rb +12 -10
  66. data/lib/sequel/adapters/shared/access.rb +6 -0
  67. data/lib/sequel/adapters/shared/cubrid.rb +2 -0
  68. data/lib/sequel/adapters/shared/db2.rb +2 -0
  69. data/lib/sequel/adapters/shared/firebird.rb +2 -0
  70. data/lib/sequel/adapters/shared/informix.rb +2 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +14 -8
  72. data/lib/sequel/adapters/shared/mysql.rb +6 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +2 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +14 -4
  75. data/lib/sequel/adapters/shared/progress.rb +1 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +4 -3
  77. data/lib/sequel/adapters/sqlite.rb +6 -7
  78. data/lib/sequel/adapters/swift.rb +20 -21
  79. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  80. data/lib/sequel/adapters/swift/postgres.rb +2 -0
  81. data/lib/sequel/adapters/swift/sqlite.rb +1 -0
  82. data/lib/sequel/adapters/tinytds.rb +5 -6
  83. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
  84. data/lib/sequel/connection_pool.rb +1 -1
  85. data/lib/sequel/core.rb +57 -50
  86. data/lib/sequel/database/connecting.rb +9 -10
  87. data/lib/sequel/database/dataset.rb +11 -6
  88. data/lib/sequel/database/dataset_defaults.rb +61 -69
  89. data/lib/sequel/database/features.rb +21 -0
  90. data/lib/sequel/database/misc.rb +23 -3
  91. data/lib/sequel/database/query.rb +13 -7
  92. data/lib/sequel/database/schema_methods.rb +6 -6
  93. data/lib/sequel/database/transactions.rb +1 -0
  94. data/lib/sequel/dataset/actions.rb +51 -38
  95. data/lib/sequel/dataset/features.rb +1 -0
  96. data/lib/sequel/dataset/graph.rb +9 -33
  97. data/lib/sequel/dataset/misc.rb +30 -5
  98. data/lib/sequel/dataset/mutation.rb +2 -3
  99. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  100. data/lib/sequel/dataset/query.rb +91 -27
  101. data/lib/sequel/dataset/sql.rb +40 -6
  102. data/lib/sequel/deprecated.rb +74 -0
  103. data/lib/sequel/deprecated_core_extensions.rb +135 -0
  104. data/lib/sequel/extensions/columns_introspection.rb +1 -5
  105. data/lib/sequel/extensions/core_extensions.rb +10 -3
  106. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  107. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
  108. data/lib/sequel/extensions/filter_having.rb +58 -0
  109. data/lib/sequel/extensions/graph_each.rb +63 -0
  110. data/lib/sequel/extensions/hash_aliases.rb +44 -0
  111. data/lib/sequel/extensions/looser_typecasting.rb +14 -3
  112. data/lib/sequel/extensions/migration.rb +2 -3
  113. data/lib/sequel/extensions/named_timezones.rb +14 -1
  114. data/lib/sequel/extensions/null_dataset.rb +7 -1
  115. data/lib/sequel/extensions/pagination.rb +15 -5
  116. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
  117. data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
  118. data/lib/sequel/extensions/pg_json.rb +7 -7
  119. data/lib/sequel/extensions/pg_range_ops.rb +8 -2
  120. data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
  121. data/lib/sequel/extensions/pretty_table.rb +13 -4
  122. data/lib/sequel/extensions/query.rb +21 -4
  123. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
  124. data/lib/sequel/extensions/schema_caching.rb +10 -7
  125. data/lib/sequel/extensions/schema_dumper.rb +35 -48
  126. data/lib/sequel/extensions/select_remove.rb +13 -4
  127. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
  128. data/lib/sequel/extensions/set_overrides.rb +43 -0
  129. data/lib/sequel/extensions/to_dot.rb +6 -0
  130. data/lib/sequel/model.rb +12 -6
  131. data/lib/sequel/model/associations.rb +80 -38
  132. data/lib/sequel/model/base.rb +137 -52
  133. data/lib/sequel/model/errors.rb +7 -2
  134. data/lib/sequel/plugins/active_model.rb +13 -0
  135. data/lib/sequel/plugins/after_initialize.rb +43 -0
  136. data/lib/sequel/plugins/association_proxies.rb +63 -7
  137. data/lib/sequel/plugins/auto_validations.rb +56 -16
  138. data/lib/sequel/plugins/blacklist_security.rb +63 -0
  139. data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
  140. data/lib/sequel/plugins/constraint_validations.rb +50 -8
  141. data/lib/sequel/plugins/dataset_associations.rb +2 -0
  142. data/lib/sequel/plugins/hook_class_methods.rb +7 -1
  143. data/lib/sequel/plugins/identity_map.rb +4 -0
  144. data/lib/sequel/plugins/json_serializer.rb +32 -13
  145. data/lib/sequel/plugins/optimistic_locking.rb +1 -1
  146. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  147. data/lib/sequel/plugins/scissors.rb +33 -0
  148. data/lib/sequel/plugins/serialization.rb +1 -1
  149. data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
  150. data/lib/sequel/plugins/tree.rb +5 -1
  151. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  152. data/lib/sequel/plugins/validation_helpers.rb +15 -11
  153. data/lib/sequel/plugins/xml_serializer.rb +12 -3
  154. data/lib/sequel/sql.rb +12 -2
  155. data/lib/sequel/timezones.rb +1 -1
  156. data/lib/sequel/version.rb +1 -1
  157. data/lib/sequel_core.rb +1 -0
  158. data/lib/sequel_model.rb +1 -0
  159. data/spec/adapters/mssql_spec.rb +24 -57
  160. data/spec/adapters/postgres_spec.rb +27 -55
  161. data/spec/adapters/spec_helper.rb +1 -1
  162. data/spec/adapters/sqlite_spec.rb +1 -1
  163. data/spec/bin_spec.rb +251 -0
  164. data/spec/core/database_spec.rb +46 -32
  165. data/spec/core/dataset_spec.rb +233 -181
  166. data/spec/core/deprecated_spec.rb +78 -0
  167. data/spec/core/expression_filters_spec.rb +3 -4
  168. data/spec/core/mock_adapter_spec.rb +9 -9
  169. data/spec/core/object_graph_spec.rb +9 -19
  170. data/spec/core/schema_spec.rb +3 -1
  171. data/spec/core/spec_helper.rb +19 -0
  172. data/spec/core_extensions_spec.rb +80 -30
  173. data/spec/extensions/after_initialize_spec.rb +24 -0
  174. data/spec/extensions/association_proxies_spec.rb +37 -1
  175. data/spec/extensions/auto_validations_spec.rb +20 -4
  176. data/spec/extensions/blacklist_security_spec.rb +87 -0
  177. data/spec/extensions/boolean_readers_spec.rb +2 -1
  178. data/spec/extensions/class_table_inheritance_spec.rb +7 -0
  179. data/spec/extensions/columns_introspection_spec.rb +3 -3
  180. data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
  181. data/spec/extensions/core_refinements_spec.rb +7 -7
  182. data/spec/extensions/dataset_associations_spec.rb +2 -2
  183. data/spec/extensions/date_arithmetic_spec.rb +1 -1
  184. data/spec/extensions/defaults_setter_spec.rb +2 -1
  185. data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
  186. data/spec/extensions/filter_having_spec.rb +40 -0
  187. data/spec/extensions/graph_each_spec.rb +109 -0
  188. data/spec/extensions/hash_aliases_spec.rb +16 -0
  189. data/spec/extensions/hook_class_methods_spec.rb +2 -2
  190. data/spec/extensions/identity_map_spec.rb +3 -3
  191. data/spec/extensions/json_serializer_spec.rb +19 -19
  192. data/spec/extensions/lazy_attributes_spec.rb +1 -0
  193. data/spec/extensions/list_spec.rb +13 -13
  194. data/spec/extensions/looser_typecasting_spec.rb +10 -3
  195. data/spec/extensions/many_through_many_spec.rb +1 -1
  196. data/spec/extensions/migration_spec.rb +7 -7
  197. data/spec/extensions/named_timezones_spec.rb +6 -0
  198. data/spec/extensions/nested_attributes_spec.rb +2 -2
  199. data/spec/extensions/null_dataset_spec.rb +1 -1
  200. data/spec/extensions/pagination_spec.rb +2 -2
  201. data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
  202. data/spec/extensions/pg_range_ops_spec.rb +4 -2
  203. data/spec/extensions/pg_row_plugin_spec.rb +1 -1
  204. data/spec/extensions/pretty_table_spec.rb +1 -1
  205. data/spec/extensions/query_literals_spec.rb +1 -1
  206. data/spec/extensions/query_spec.rb +3 -3
  207. data/spec/extensions/schema_caching_spec.rb +3 -3
  208. data/spec/extensions/schema_dumper_spec.rb +27 -2
  209. data/spec/extensions/schema_spec.rb +2 -2
  210. data/spec/extensions/scissors_spec.rb +26 -0
  211. data/spec/extensions/select_remove_spec.rb +1 -1
  212. data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
  213. data/spec/extensions/set_overrides_spec.rb +45 -0
  214. data/spec/extensions/single_table_inheritance_spec.rb +10 -0
  215. data/spec/extensions/spec_helper.rb +24 -1
  216. data/spec/extensions/static_cache_spec.rb +1 -1
  217. data/spec/extensions/string_stripper_spec.rb +2 -1
  218. data/spec/extensions/to_dot_spec.rb +1 -1
  219. data/spec/extensions/typecast_on_load_spec.rb +3 -2
  220. data/spec/extensions/update_primary_key_spec.rb +2 -2
  221. data/spec/extensions/validation_class_methods_spec.rb +19 -19
  222. data/spec/extensions/validation_helpers_spec.rb +30 -21
  223. data/spec/extensions/xml_serializer_spec.rb +5 -5
  224. data/spec/integration/associations_test.rb +10 -30
  225. data/spec/integration/dataset_test.rb +20 -24
  226. data/spec/integration/eager_loader_test.rb +5 -5
  227. data/spec/integration/model_test.rb +3 -3
  228. data/spec/integration/plugin_test.rb +7 -39
  229. data/spec/integration/schema_test.rb +4 -38
  230. data/spec/integration/spec_helper.rb +2 -1
  231. data/spec/model/association_reflection_spec.rb +70 -5
  232. data/spec/model/associations_spec.rb +11 -11
  233. data/spec/model/base_spec.rb +25 -8
  234. data/spec/model/class_dataset_methods_spec.rb +143 -0
  235. data/spec/model/dataset_methods_spec.rb +1 -1
  236. data/spec/model/eager_loading_spec.rb +25 -25
  237. data/spec/model/hooks_spec.rb +1 -1
  238. data/spec/model/model_spec.rb +22 -7
  239. data/spec/model/plugins_spec.rb +1 -6
  240. data/spec/model/record_spec.rb +37 -29
  241. data/spec/model/spec_helper.rb +23 -1
  242. data/spec/model/validations_spec.rb +15 -17
  243. metadata +32 -3
@@ -79,8 +79,14 @@ module Sequel
79
79
  OPERATORS.keys.each do |f|
80
80
  class_eval("def #{f}(v); operator(:#{f}, v) end", __FILE__, __LINE__)
81
81
  end
82
- alias starts_before ends_before
83
- alias ends_after starts_after
82
+ def starts_before(v)
83
+ Sequel::Deprecation.deprecate('Postgres::PGRangeOp#starts_before', "Please switch to Postgres::PGRangeOp#ends_before")
84
+ ends_before(v)
85
+ end
86
+ def ends_after(v)
87
+ Sequel::Deprecation.deprecate('Postgres::PGRangeOp#ends_after', "Please switch to Postgres::PGRangeOp#starts_after")
88
+ starts_after(v)
89
+ end
84
90
 
85
91
  # These operators are already supported by the wrapper, but for ranges they
86
92
  # return ranges, so wrap the results in another RangeOp.
@@ -228,6 +228,7 @@ module Sequel
228
228
  # Set the statement_cache for the connection, using the database's
229
229
  # :statement_cache_opts option.
230
230
  def self.extended(c)
231
+ Sequel::Deprecation.deprecate('The pg_statement_cache extension', 'Please stop loading it') unless defined?(SEQUEL_EXTENSIONS_NO_DEPRECATION_WARNING)
231
232
  c.instance_variable_set(:@statement_cache, StatementCache.new(c.sequel_db.opts[:statement_cache_opts] || {}){|name| c.deallocate(name)})
232
233
  end
233
234
 
@@ -9,22 +9,31 @@
9
9
  # |2 |test |
10
10
  # +--+-------+
11
11
  #
12
- # To load the extension:
12
+ # You can load this extension into specific datasets:
13
13
  #
14
- # Sequel.extension :pretty_table
14
+ # ds = DB[:table]
15
+ # ds.extension(:pretty_table)
16
+ #
17
+ # Or you can load it into all of a database's datasets, which
18
+ # is probably the desired behavior if you are using this extension:
19
+ #
20
+ # DB.extension(:pretty_table)
15
21
 
16
22
  module Sequel
17
23
  extension :_pretty_table
18
24
 
25
+ module DatasetPrinter
26
+ end
27
+
19
28
  class Dataset
20
29
  # Pretty prints the records in the dataset as plain-text table.
21
30
  def print(*cols)
31
+ Sequel::Deprecation.deprecate('Loading the pretty_table extension globally', "Please use Database/Dataset#extension to load the extension into this dataset") unless is_a?(DatasetPrinter)
22
32
  ds = naked
23
33
  rows = ds.all
24
34
  Sequel::PrettyTable.print(rows, cols.empty? ? ds.columns : cols)
25
35
  end
26
36
  end
27
37
 
28
- Database.register_extension(:pretty_table){}
29
- Dataset.register_extension(:pretty_table){}
38
+ Dataset.register_extension(:pretty_table, DatasetPrinter)
30
39
  end
@@ -2,18 +2,34 @@
2
2
  # a different way to construct queries instead of the usual
3
3
  # method chaining. See Sequel::Dataset#query for details.
4
4
  #
5
- # To load the extension, do:
5
+ # You can load this extension into specific datasets:
6
6
  #
7
- # Sequel.extension :query
7
+ # ds = DB[:table]
8
+ # ds.extension(:query)
9
+ #
10
+ # Or you can load it into all of a database's datasets, which
11
+ # is probably the desired behavior if you are using this extension:
12
+ #
13
+ # DB.extension(:query)
8
14
 
9
15
  module Sequel
16
+ module DatabaseQuery
17
+ def self.extended(db)
18
+ db.extend_datasets(DatasetQuery)
19
+ end
20
+ end
21
+
10
22
  class Database
11
23
  # Return a dataset modified by the query block
12
24
  def query(&block)
25
+ Sequel::Deprecation.deprecate('Loading the query extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(DatabaseQuery)
13
26
  dataset.query(&block)
14
27
  end
15
28
  end
16
29
 
30
+ module DatasetQuery
31
+ end
32
+
17
33
  class Dataset
18
34
  # Translates a query block into a dataset. Query blocks are an
19
35
  # alternative to Sequel's usual method chaining, by using
@@ -29,6 +45,7 @@ module Sequel
29
45
  #
30
46
  # dataset = DB[:items].select(:x, :y, :z).filter{(x > 1) & (y > 2)}.reverse(:z)
31
47
  def query(&block)
48
+ Sequel::Deprecation.deprecate('Loading the query extension globally', "Please use Database/Dataset#extension to load the extension into this dataset") unless is_a?(DatasetQuery)
32
49
  query = Query.new(self)
33
50
  query.instance_eval(&block)
34
51
  query.dataset
@@ -52,6 +69,6 @@ module Sequel
52
69
  end
53
70
  end
54
71
 
55
- Dataset.register_extension(:query){}
56
- Database.register_extension(:query){}
72
+ Dataset.register_extension(:query, DatasetQuery)
73
+ Database.register_extension(:query, DatabaseQuery)
57
74
  end
@@ -0,0 +1,22 @@
1
+ # The ruby18_symbol_extensions adds the <, <=, >, >= to Symbol
2
+ # to reflect the mathmatical operators. It also adds the [] method
3
+ # to Symbol for creating SQL functions.
4
+ #
5
+ # Usage of this extension is not recommended. This extension will
6
+ # only load on ruby 1.8, so you will not be able to upgrade to
7
+ # newer ruby versions if you use it. If you still want to use it,
8
+ # you can load it via:
9
+ #
10
+ # Sequel.extension :ruby18_symbol_extensions
11
+
12
+ raise(Sequel::Error, "The ruby18_symbol_extensions is only available on ruby 1.8.") unless RUBY_VERSION < '1.9.0'
13
+
14
+ class Symbol
15
+ include Sequel::SQL::InequalityMethods
16
+
17
+ # Create an SQL Function with the receiver as the function name
18
+ # and the given arguments.
19
+ def [](*args)
20
+ Sequel::SQL::Function.new(self, *args)
21
+ end
22
+ end
@@ -6,10 +6,8 @@
6
6
  #
7
7
  # Basic usage in application code:
8
8
  #
9
- # Sequel.extension :schema_caching
10
- #
11
9
  # DB = Sequel.connect('...')
12
- #
10
+ # DB.extension :schema_caching
13
11
  # DB.load_schema_cache('/path/to/schema.dump')
14
12
  #
15
13
  # # load model files
@@ -23,10 +21,8 @@
23
21
  # all tables, and you don't worry about race conditions, you can
24
22
  # choose to use the following in your application code:
25
23
  #
26
- # Sequel.extension :schema_caching
27
- #
28
24
  # DB = Sequel.connect('...')
29
- #
25
+ # DB.extension :schema_caching
30
26
  # DB.load_schema_cache?('/path/to/schema.dump')
31
27
  #
32
28
  # # load model files
@@ -47,9 +43,13 @@
47
43
  # you should not attempt to load the schema from a untrusted file.
48
44
 
49
45
  module Sequel
46
+ module SchemaCaching
47
+ end
48
+
50
49
  class Database
51
50
  # Dump the cached schema to the filename given in Marshal format.
52
51
  def dump_schema_cache(file)
52
+ Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
53
53
  File.open(file, 'wb'){|f| f.write(Marshal.dump(@schemas))}
54
54
  nil
55
55
  end
@@ -57,12 +57,14 @@ module Sequel
57
57
  # Dump the cached schema to the filename given unless the file
58
58
  # already exists.
59
59
  def dump_schema_cache?(file)
60
+ Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
60
61
  dump_schema_cache(file) unless File.exist?(file)
61
62
  end
62
63
 
63
64
  # Replace the schema cache with the data from the given file, which
64
65
  # should be in Marshal format.
65
66
  def load_schema_cache(file)
67
+ Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
66
68
  @schemas = Marshal.load(File.read(file))
67
69
  nil
68
70
  end
@@ -70,9 +72,10 @@ module Sequel
70
72
  # Replace the schema cache with the data from the given file if the
71
73
  # file exists.
72
74
  def load_schema_cache?(file)
75
+ Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
73
76
  load_schema_cache(file) if File.exist?(file)
74
77
  end
75
78
  end
76
79
 
77
- Database.register_extension(:schema_caching){}
80
+ Database.register_extension(:schema_caching, SchemaCaching)
78
81
  end
@@ -6,11 +6,14 @@
6
6
  #
7
7
  # To load the extension:
8
8
  #
9
- # Sequel.extension :schema_dumper
9
+ # DB.extension :schema_dumper
10
10
 
11
11
  Sequel.extension :eval_inspect
12
12
 
13
13
  module Sequel
14
+ module SchemaDumper
15
+ end
16
+
14
17
  class Database
15
18
  # Dump foreign key constraints for all tables as a migration. This complements
16
19
  # the :foreign_keys=>false option to dump_schema_migration. This only dumps
@@ -20,6 +23,7 @@ module Sequel
20
23
  # Note that the migration this produces does not have a down
21
24
  # block, so you cannot reverse it.
22
25
  def dump_foreign_key_migration(options={})
26
+ Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
23
27
  ts = tables(options)
24
28
  <<END_MIG
25
29
  Sequel.migration do
@@ -38,6 +42,7 @@ END_MIG
38
42
  # set to :namespace, prepend the table name to the index name if the
39
43
  # database does not use a global index namespace.
40
44
  def dump_indexes_migration(options={})
45
+ Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
41
46
  ts = tables(options)
42
47
  <<END_MIG
43
48
  Sequel.migration do
@@ -62,6 +67,7 @@ END_MIG
62
67
  # :index_names :: If set to false, don't record names of indexes. If
63
68
  # set to :namespace, prepend the table name to the index name.
64
69
  def dump_schema_migration(options={})
70
+ Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
65
71
  options = options.dup
66
72
  if options[:indexes] == false && !options.has_key?(:foreign_keys)
67
73
  # Unless foreign_keys option is specifically set, disable if indexes
@@ -91,6 +97,7 @@ END_MIG
91
97
  # Return a string with a create table block that will recreate the given
92
98
  # table's schema. Takes the same options as dump_schema_migration.
93
99
  def dump_table_schema(table, options={})
100
+ Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
94
101
  table = table.value.to_s if table.is_a?(SQL::Identifier)
95
102
  gen = dump_table_generator(table, options)
96
103
  commands = [gen.dump_columns, gen.dump_constraints, gen.dump_indexes].reject{|x| x == ''}.join("\n\n")
@@ -209,13 +216,11 @@ END_MIG
209
216
  # For the table given, get the list of foreign keys and return an alter_table
210
217
  # string that would add the foreign keys if run in a migration.
211
218
  def dump_table_foreign_keys(table, options={})
212
- begin
219
+ if supports_foreign_key_parsing?
213
220
  fks = foreign_key_list(table, options).sort_by{|fk| fk[:columns].map{|c| c.to_s}}
214
- rescue Sequel::NotImplemented
215
- return ''
216
221
  end
217
222
 
218
- if fks.empty?
223
+ if fks.nil? || fks.empty?
219
224
  ''
220
225
  else
221
226
  dump_add_fk_constraints(table, fks)
@@ -233,40 +238,32 @@ END_MIG
233
238
  m = method(:recreate_column)
234
239
  im = method(:index_to_generator_opts)
235
240
 
236
- if options[:indexes] != false
237
- begin
238
- indexes = indexes(table).sort_by{|k,v| k.to_s}
239
- rescue Sequel::NotImplemented
240
- nil
241
- end
241
+ if options[:indexes] != false && supports_index_parsing?
242
+ indexes = indexes(table).sort_by{|k,v| k.to_s}
242
243
  end
243
244
 
244
- if options[:foreign_keys] != false
245
- begin
246
- fk_list = foreign_key_list(table)
247
-
248
- if (sfk = options[:skipped_foreign_keys]) && (sfkt = sfk[table])
249
- fk_list.delete_if{|fk| sfkt.has_key?(fk[:columns])}
250
- end
245
+ if options[:foreign_keys] != false && supports_foreign_key_parsing?
246
+ fk_list = foreign_key_list(table)
247
+
248
+ if (sfk = options[:skipped_foreign_keys]) && (sfkt = sfk[table])
249
+ fk_list.delete_if{|fk| sfkt.has_key?(fk[:columns])}
250
+ end
251
251
 
252
- composite_fks, single_fks = fk_list.partition{|h| h[:columns].length > 1}
253
- fk_hash = {}
252
+ composite_fks, single_fks = fk_list.partition{|h| h[:columns].length > 1}
253
+ fk_hash = {}
254
254
 
255
- single_fks.each do |fk|
256
- column = fk.delete(:columns).first
257
- fk.delete(:name)
258
- fk_hash[column] = fk
259
- end
255
+ single_fks.each do |fk|
256
+ column = fk.delete(:columns).first
257
+ fk.delete(:name)
258
+ fk_hash[column] = fk
259
+ end
260
260
 
261
- s = s.map do |name, info|
262
- if fk_info = fk_hash[name]
263
- [name, fk_info.merge(info)]
264
- else
265
- [name, info]
266
- end
261
+ s = s.map do |name, info|
262
+ if fk_info = fk_hash[name]
263
+ [name, fk_info.merge(info)]
264
+ else
265
+ [name, info]
267
266
  end
268
- rescue Sequel::NotImplemented
269
- nil
270
267
  end
271
268
  end
272
269
 
@@ -281,11 +278,12 @@ END_MIG
281
278
  # Return a string that containing add_index/drop_index method calls for
282
279
  # creating the index migration.
283
280
  def dump_table_indexes(table, meth, options={})
284
- begin
281
+ if supports_index_parsing?
285
282
  indexes = indexes(table).sort_by{|k,v| k.to_s}
286
- rescue Sequel::NotImplemented
283
+ else
287
284
  return ''
288
285
  end
286
+
289
287
  im = method(:index_to_generator_opts)
290
288
  gen = create_table_generator do
291
289
  indexes.each{|iname, iopts| send(:index, iopts[:columns], im.call(table, iname, iopts, options))}
@@ -311,18 +309,7 @@ END_MIG
311
309
  # Sort the tables so that referenced tables are created before tables that
312
310
  # reference them, and then by name. If foreign keys are disabled, just sort by name.
313
311
  def sort_dumped_tables(tables, options={})
314
- sort_topologically = if options[:foreign_keys] != false
315
- begin
316
- foreign_key_list(:some_table_that_does_not_exist)
317
- true
318
- rescue Sequel::NotImplemented
319
- false
320
- rescue
321
- true
322
- end
323
- end
324
-
325
- if sort_topologically
312
+ if options[:foreign_keys] != false && supports_foreign_key_parsing?
326
313
  table_fks = {}
327
314
  tables.each{|t| table_fks[t] = foreign_key_list(t)}
328
315
  # Remove self referential foreign keys, not important when sorting.
@@ -484,5 +471,5 @@ END_MIG
484
471
  end
485
472
  end
486
473
 
487
- Database.register_extension(:schema_dumper){}
474
+ Database.register_extension(:schema_dumper, SchemaDumper)
488
475
  end
@@ -2,11 +2,20 @@
2
2
  # columns from a dataset. It's not part of Sequel core as it is rarely needed and has
3
3
  # some corner cases where it can't work correctly.
4
4
  #
5
- # To load the extension:
5
+ # You can load this extension into specific datasets:
6
6
  #
7
- # Sequel.extension :select_remove
7
+ # ds = DB[:table]
8
+ # ds.extension(:select_remove)
9
+ #
10
+ # Or you can load it into all of a database's datasets, which
11
+ # is probably the desired behavior if you are using this extension:
12
+ #
13
+ # DB.extension(:select_remove)
8
14
 
9
15
  module Sequel
16
+ module SelectRemove
17
+ end
18
+
10
19
  class Dataset
11
20
  # Remove columns from the list of selected columns. If any of the currently selected
12
21
  # columns use expressions/aliases, this will remove selected columns with the given
@@ -29,6 +38,7 @@ module Sequel
29
38
  #
30
39
  # There may be other cases where this method does not work correctly, use it with caution.
31
40
  def select_remove(*cols)
41
+ Sequel::Deprecation.deprecate('Loading the select_remove extension globally', "Please use Database/Dataset#extension to load the extension into this dataset") unless is_a?(SelectRemove)
32
42
  if (sel = @opts[:select]) && !sel.empty?
33
43
  select(*(columns.zip(sel).reject{|c, s| cols.include?(c)}.map{|c, s| s} - cols))
34
44
  else
@@ -37,6 +47,5 @@ module Sequel
37
47
  end
38
48
  end
39
49
 
40
- Database.register_extension(:select_remove){}
41
- Dataset.register_extension(:select_remove){}
50
+ Dataset.register_extension(:select_remove, SelectRemove)
42
51
  end
@@ -0,0 +1,117 @@
1
+ # This adds the following dataset methods:
2
+ #
3
+ # []= :: filter with the first argument, update with the second
4
+ # insert_multiple :: insert multiple rows at once
5
+ # set :: alias for update
6
+ # to_csv :: return string in csv format for the dataset
7
+ # db= :: change the dataset's database
8
+ # opts= :: change the dataset's opts
9
+ #
10
+ # It is only recommended to use this for backwards compatibility.
11
+ #
12
+ # You can load this extension into specific datasets:
13
+ #
14
+ # ds = DB[:table]
15
+ # ds.extension(:sequel_3_dataset_methods)
16
+ #
17
+ # Or you can load it into all of a database's datasets, which
18
+ # is probably the desired behavior if you are using this extension:
19
+ #
20
+ # DB.extension(:sequel_3_dataset_methods)
21
+
22
+ module Sequel
23
+ module Sequel3DatasetMethods
24
+ COMMA = Dataset::COMMA
25
+ # The database related to this dataset. This is the Database instance that
26
+ # will execute all of this dataset's queries.
27
+ attr_writer :db
28
+
29
+ # The hash of options for this dataset, keys are symbols.
30
+ attr_writer :opts
31
+
32
+ # Update all records matching the conditions with the values specified.
33
+ # Returns the number of rows affected.
34
+ #
35
+ # DB[:table][:id=>1] = {:id=>2} # UPDATE table SET id = 2 WHERE id = 1
36
+ # # => 1 # number of rows affected
37
+ def []=(conditions, values)
38
+ filter(conditions).update(values)
39
+ end
40
+
41
+ # Inserts multiple values. If a block is given it is invoked for each
42
+ # item in the given array before inserting it. See +multi_insert+ as
43
+ # a possibly faster version that may be able to insert multiple
44
+ # records in one SQL statement (if supported by the database).
45
+ # Returns an array of primary keys of inserted rows.
46
+ #
47
+ # DB[:table].insert_multiple([{:x=>1}, {:x=>2}])
48
+ # # => [4, 5]
49
+ # # INSERT INTO table (x) VALUES (1)
50
+ # # INSERT INTO table (x) VALUES (2)
51
+ #
52
+ # DB[:table].insert_multiple([{:x=>1}, {:x=>2}]){|row| row[:y] = row[:x] * 2; row }
53
+ # # => [6, 7]
54
+ # # INSERT INTO table (x, y) VALUES (1, 2)
55
+ # # INSERT INTO table (x, y) VALUES (2, 4)
56
+ def insert_multiple(array, &block)
57
+ if block
58
+ array.map{|i| insert(block.call(i))}
59
+ else
60
+ array.map{|i| insert(i)}
61
+ end
62
+ end
63
+
64
+ # Return a copy of the dataset with unqualified identifiers in the
65
+ # SELECT, WHERE, GROUP, HAVING, and ORDER clauses qualified by the
66
+ # given table. If no columns are currently selected, select all
67
+ # columns of the given table.
68
+ #
69
+ # DB[:items].filter(:id=>1).qualify_to(:i)
70
+ # # SELECT i.* FROM items WHERE (i.id = 1)
71
+ def qualify_to(table)
72
+ qualify(table)
73
+ end
74
+
75
+ # Qualify the dataset to its current first source. This is useful
76
+ # if you have unqualified identifiers in the query that all refer to
77
+ # the first source, and you want to join to another table which
78
+ # has columns with the same name as columns in the current dataset.
79
+ # See +qualify_to+.
80
+ #
81
+ # DB[:items].filter(:id=>1).qualify_to_first_source
82
+ # # SELECT items.* FROM items WHERE (items.id = 1)
83
+ def qualify_to_first_source
84
+ qualify
85
+ end
86
+
87
+ # Alias for update, but not aliased directly so subclasses
88
+ # don't have to override both methods.
89
+ def set(*args)
90
+ update(*args)
91
+ end
92
+
93
+ # Returns a string in CSV format containing the dataset records. By
94
+ # default the CSV representation includes the column titles in the
95
+ # first line. You can turn that off by passing false as the
96
+ # include_column_titles argument.
97
+ #
98
+ # This does not use a CSV library or handle quoting of values in
99
+ # any way. If any values in any of the rows could include commas or line
100
+ # endings, you shouldn't use this.
101
+ #
102
+ # puts DB[:table].to_csv # SELECT * FROM table
103
+ # # id,name
104
+ # # 1,Jim
105
+ # # 2,Bob
106
+ def to_csv(include_column_titles = true)
107
+ n = naked
108
+ cols = n.columns
109
+ csv = ''
110
+ csv << "#{cols.join(COMMA)}\r\n" if include_column_titles
111
+ n.each{|r| csv << "#{cols.collect{|c| r[c]}.join(COMMA)}\r\n"}
112
+ csv
113
+ end
114
+ end
115
+
116
+ Dataset.register_extension(:sequel_3_dataset_methods, Sequel3DatasetMethods)
117
+ end