sequel 4.28.0 → 4.29.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4342ce776d6f7e929b8ef1e9621f79f4544357b4
4
- data.tar.gz: 64ed417591b155d46f3ca0abdbe38f515ea9e15f
3
+ metadata.gz: f1baf17a3ed5aedeadf0002e4e68ac8e2e27bdc2
4
+ data.tar.gz: 9ceec8f5898df4025b6cf5239f461dee5595ebeb
5
5
  SHA512:
6
- metadata.gz: 2e672203108c7301da9abcaf7596368a1aa09b8302175bb6f49d9bc189993a84e7089343e16fcdb69b9409d3677746694b36e7cbb25d1c179779ab605cd63343
7
- data.tar.gz: 198aa8d381bd263e27bb03b646f0fa50d45225b5370084236d6da55eb1f6032396c6548f114c8ccf0d187091ab2a195c5d298e62e5a185bf992ce4fb06615d15
6
+ metadata.gz: a2c9116e35e8ff8a536530cff484f2d82fac1916db18d8d4b4666359c6ce1f6a67aeb855feb173128f874a179bc75ef10a22bd326ecf48ad6c3cfbe6f3f3b8d3
7
+ data.tar.gz: 07d8ee3fb38aeae9caa9344756826a7e43fa19bd5786948525b427e9d64c3714ee06d452299b310bb7d30666e16ee0af64f663de7bb9a3dbd3b2fd0f2c5255dd
data/CHANGELOG CHANGED
@@ -1,3 +1,23 @@
1
+ === 4.29.0 (2015-12-01)
2
+
3
+ * Add Model#json_serializer_opts method to json_serializer plugin, allowing for setting to_json defaults on per-instance basis (jeremyevans)
4
+
5
+ * Add uuid plugin for automatically setting UUID column when creating a model object (pdrakeweb, jeremyevans) (#1106)
6
+
7
+ * Allow the sqlanywhere adapter to work with sharding (jeremyevans)
8
+
9
+ * Support blobs as bound variables in the oracle adapter (jeremyevans) (#1104)
10
+
11
+ * Order by best results first when using the Database#full_text_search :rank option on PostgreSQL (chanks) (#1101)
12
+
13
+ * Run Database#table_exists? inside a savepoint if currently in a transaction and the database supports savepoints (jeremyevans) (#1100)
14
+
15
+ * Allow Database#transaction :retry_on option to work when using savepoints (jeremyevans)
16
+
17
+ * Allow for external adapters to implement Dataset#date_add_sql_append to integrate with the date_arithmetic extension (jeremyevans)
18
+
19
+ * Add Dataset#insert_empty_columns_values private method for easy overriding for databases that don't support INSERT with DEFAULT VALUES (jeremyevans)
20
+
1
21
  === 4.28.0 (2015-11-02)
2
22
 
3
23
  * Add boolean_subsets plugin, which adds a subset for each boolean column (jeremyevans)
@@ -44,7 +44,7 @@ If you have any comments or suggestions please post to the Google group.
44
44
 
45
45
  require 'sequel'
46
46
 
47
- DB = Sequel.sqlite # memory database
47
+ DB = Sequel.sqlite # memory database, requires sqlite3
48
48
 
49
49
  DB.create_table :items do
50
50
  primary_key :id
@@ -109,11 +109,11 @@ Or getting results as a hash via +to_hash+, with one column as key and another a
109
109
  To connect to a database you simply provide <tt>Sequel.connect</tt> with a URL:
110
110
 
111
111
  require 'sequel'
112
- DB = Sequel.connect('sqlite://blog.db')
112
+ DB = Sequel.connect('sqlite://blog.db') # requires sqlite3
113
113
 
114
114
  The connection URL can also include such stuff as the user name, password, and port:
115
115
 
116
- DB = Sequel.connect('postgres://user:password@host:port/database_name')
116
+ DB = Sequel.connect('postgres://user:password@host:port/database_name') # requires pg
117
117
 
118
118
  You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
119
119
 
@@ -267,7 +267,7 @@ issues that you should be aware of when using Sequel.
267
267
 
268
268
  Counting records is easy using +count+:
269
269
 
270
- posts.where(:category.like('%ruby%')).count
270
+ posts.where(Sequel.like(:category, '%ruby%')).count
271
271
  # SELECT COUNT(*) FROM posts WHERE category LIKE '%ruby%'
272
272
 
273
273
  And you can also query maximum/minimum values via +max+ and +min+:
@@ -269,12 +269,8 @@ The following additional options are supported:
269
269
  === mysql2
270
270
 
271
271
  This is a newer MySQL adapter that does typecasting in C, so it is often faster than the
272
- mysql adapter. Supports the same additional options as the mysql adapter, except for :compress, and uses
273
- :timeout instead of :read_timeout and :connect_timeout.
274
-
275
- The following additional options are supported:
276
-
277
- :flags :: Override the flags to use for the connection (e.g. ::Mysql2::Client::MULTI_STATEMENTS)
272
+ mysql adapter. The options given are passed to Mysql2::Client.new, see the mysql2 documentation
273
+ for details on what options are supported.
278
274
 
279
275
  === odbc
280
276
 
@@ -0,0 +1,41 @@
1
+ = New Features
2
+
3
+ * A uuid plugin has now been added. This plugin will automatically
4
+ create a uuid for newly created model objects.
5
+
6
+ Model.plugin :uuid
7
+ Model.create.uuid => # some UUID
8
+
9
+ * Model#json_serializer_opts has been added to the json_serializer
10
+ plugin, allowing you to override the JSON serialization options
11
+ on a per instance basis without passing the options directly
12
+ to Model#to_json. This is useful if you are including the model
13
+ instance inside another datastructure that will be serialized
14
+ to JSON.
15
+
16
+ obj.json_serializer_opts(:root => true)
17
+ [obj].to_json
18
+ # => '[{"obj":{"id":1,"name":"Foo"}}]'
19
+
20
+ = Other Improvements
21
+
22
+ * The Database#transaction :retry_on option now works when using
23
+ savepoints.
24
+
25
+ * Calling Database#table_exists? inside a transaction will now use
26
+ a savepoint if the database supports it, so that if the table
27
+ doesn't exist, it will not affect the state of the transaction.
28
+
29
+ * Blobs can now be used as bound variables in the oracle adapter.
30
+
31
+ * The sqlanywhere adapter now works with database sharding.
32
+
33
+ * The Dataset#full_text_search :rank option has been fixed to order
34
+ by rank descending instead of ascending.
35
+
36
+ * External adapters that do not support INSERT with DEFAULT VALUES
37
+ can now override Dataset#insert_empty_columns_values to set
38
+ the columns and values to use for an empty INSERT.
39
+
40
+ * External adapters can now implement Dataset#date_add_sql_append
41
+ to integrate with the date_arithmetic extension.
@@ -122,7 +122,7 @@ module Sequel
122
122
  when BigDecimal
123
123
  arg = arg.to_f
124
124
  when ::Sequel::SQL::Blob
125
- raise Error, "Sequel's oracle adapter does not currently support using a blob in a bound variable"
125
+ arg = ::OCI8::BLOB.new(conn, arg)
126
126
  end
127
127
  if t = PS_TYPES[type]
128
128
  cursor.bind_param(i, arg, t)
@@ -1331,7 +1331,7 @@ module Sequel
1331
1331
  end
1332
1332
 
1333
1333
  if opts[:rank]
1334
- ds = ds.order{ts_rank_cd(cols, terms)}
1334
+ ds = ds.reverse{ts_rank_cd(cols, terms)}
1335
1335
  end
1336
1336
 
1337
1337
  ds
@@ -79,19 +79,19 @@ module Sequel
79
79
 
80
80
  # Returns number of rows affected
81
81
  def execute_dui(sql, opts=OPTS)
82
- synchronize do |conn|
82
+ synchronize(opts[:server]) do |conn|
83
83
  _execute(conn, :rows, sql, opts)
84
84
  end
85
85
  end
86
86
 
87
87
  def execute(sql, opts=OPTS, &block)
88
- synchronize do |conn|
88
+ synchronize(opts[:server]) do |conn|
89
89
  _execute(conn, :select, sql, opts, &block)
90
90
  end
91
91
  end
92
92
 
93
93
  def execute_insert(sql, opts=OPTS)
94
- synchronize do |conn|
94
+ synchronize(opts[:server]) do |conn|
95
95
  _execute(conn, :insert, sql, opts)
96
96
  end
97
97
  end
@@ -191,7 +191,12 @@ module Sequel
191
191
  def table_exists?(name)
192
192
  sch, table_name = schema_and_table(name)
193
193
  name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
194
- _table_exists?(from(name))
194
+ ds = from(name)
195
+ if in_transaction? && supports_savepoints?
196
+ transaction(:savepoint=>true){_table_exists?(ds)}
197
+ else
198
+ _table_exists?(ds)
199
+ end
195
200
  true
196
201
  rescue DatabaseError
197
202
  false
@@ -96,12 +96,12 @@ module Sequel
96
96
  else
97
97
  synchronize(opts[:server]) do |conn|
98
98
  if already_in_transaction?(conn, opts)
99
- if opts[:retrying]
100
- raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
101
- end
102
99
  if opts[:savepoint] != false && (stack = _trans(conn)[:savepoints]) && stack.last
103
100
  _transaction(conn, Hash[opts].merge!(:savepoint=>true), &block)
104
101
  else
102
+ if opts[:retrying]
103
+ raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
104
+ end
105
105
  return yield(conn)
106
106
  end
107
107
  else
@@ -46,12 +46,11 @@ module Sequel
46
46
  end
47
47
 
48
48
  if values.is_a?(Array) && values.empty? && !insert_supports_empty_values?
49
- columns = [columns().last]
50
- values = [DEFAULT]
49
+ columns, values = insert_empty_columns_values
51
50
  end
52
51
  clone(:columns=>columns, :values=>values).send(:_insert_sql)
53
52
  end
54
-
53
+
55
54
  # Append a literal representation of a value to the given SQL string.
56
55
  #
57
56
  # If an unsupported object is given, an +Error+ is raised.
@@ -1116,6 +1115,12 @@ module Sequel
1116
1115
  end
1117
1116
  end
1118
1117
 
1118
+ # The columns and values to use for an empty insert if the database doesn't support
1119
+ # INSERT with DEFAULT VALUES.
1120
+ def insert_empty_columns_values
1121
+ [[columns.last], [DEFAULT]]
1122
+ end
1123
+
1119
1124
  def insert_insert_sql(sql)
1120
1125
  sql << INSERT
1121
1126
  end
@@ -66,6 +66,9 @@ module Sequel
66
66
 
67
67
  # Append the SQL fragment for the DateAdd expression to the SQL query.
68
68
  def date_add_sql_append(sql, da)
69
+ if defined?(super)
70
+ return super
71
+ end
69
72
  h = da.interval
70
73
  expr = da.expr
71
74
  cast = case db_type = db.database_type
@@ -36,6 +36,12 @@ module Sequel
36
36
  # album.to_json(:root => true)
37
37
  # # => '{"album":{"id":1,"name":"RF","artist_id":2}}'
38
38
  #
39
+ # You can specify JSON serialization options to use later:
40
+ #
41
+ # album.json_serializer_opts(:root => true)
42
+ # [album].to_json
43
+ # # => '[{"album":{"id":1,"name":"RF","artist_id":2}}]'
44
+ #
39
45
  # Additionally, +to_json+ also exists as a class and dataset method, both
40
46
  # of which return all objects in the dataset:
41
47
  #
@@ -239,6 +245,20 @@ module Sequel
239
245
  self
240
246
  end
241
247
 
248
+ # Set the json serialization options that will be used by default
249
+ # in future calls to +to_json+. This is designed for cases where
250
+ # the model object will be used inside another data structure
251
+ # which to_json is called on, and as such will not allow passing
252
+ # of arguments to +to_json+.
253
+ #
254
+ # Example:
255
+ #
256
+ # obj.json_serializer_opts(:only=>:name)
257
+ # [obj].to_json # => '[{"name":"..."}]'
258
+ def json_serializer_opts(opts=OPTS)
259
+ @json_serializer_opts = Hash[@json_serializer_opts||OPTS].merge!(opts)
260
+ end
261
+
242
262
  # Return a string in JSON format. Accepts the following
243
263
  # options:
244
264
  #
@@ -257,12 +277,13 @@ module Sequel
257
277
  # string is given, use the string as the key, otherwise
258
278
  # use an underscored version of the model's name.
259
279
  def to_json(*a)
260
- if opts = a.first.is_a?(Hash)
261
- opts = model.json_serializer_opts.merge(a.first)
280
+ opts = model.json_serializer_opts
281
+ opts = Hash[opts].merge!(@json_serializer_opts) if @json_serializer_opts
282
+ if (arg_opts = a.first).is_a?(Hash)
283
+ opts = Hash[opts].merge!(arg_opts)
262
284
  a = []
263
- else
264
- opts = model.json_serializer_opts
265
285
  end
286
+
266
287
  vals = values
267
288
  cols = if only = opts[:only]
268
289
  Array(only)
@@ -0,0 +1,72 @@
1
+ require 'securerandom'
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The uuid plugin creates hooks that automatically create a uuid for every
6
+ # instance. Note that this uses SecureRandom.uuid to create UUIDs, and
7
+ # that method is not defined on ruby 1.8.7. If you would like to use this
8
+ # on ruby 1.8.7, you need to override the Model#create_uuid private method
9
+ # to return a valid uuid.
10
+ #
11
+ # Usage:
12
+ #
13
+ # # Uuid all model instances using +uuid+
14
+ # # (called before loading subclasses)
15
+ # Sequel::Model.plugin :uuid
16
+ #
17
+ # # Uuid Album instances, with custom column name
18
+ # Album.plugin :uuid, :field=>my_uuid
19
+ module Uuid
20
+ # Configure the plugin by setting the available options. Note that
21
+ # if this method is run more than once, previous settings are ignored,
22
+ # and it will just use the settings given or the default settings. Options:
23
+ # :field :: The field to hold the uuid (default: :uuid)
24
+ # :force :: Whether to overwrite an existing uuid (default: false)
25
+ def self.configure(model, opts=OPTS)
26
+ model.instance_eval do
27
+ @uuid_field = opts[:field]||:uuid
28
+ @uuid_overwrite = opts[:force]||false
29
+ end
30
+ end
31
+
32
+ module ClassMethods
33
+ # The field to store the uuid
34
+ attr_reader :uuid_field
35
+
36
+ # Whether to overwrite the create uuid if it already exists
37
+ def uuid_overwrite?
38
+ @uuid_overwrite
39
+ end
40
+
41
+ Plugins.inherited_instance_variables(self, :@uuid_field=>nil, :@uuid_overwrite=>nil)
42
+ end
43
+
44
+ module InstanceMethods
45
+ private
46
+
47
+ # Set the uuid when creating
48
+ def _before_validation
49
+ set_uuid if new?
50
+ super
51
+ end
52
+
53
+ # Create a new UUID. This method can be overridden to use a separate
54
+ # method for creating UUIDs. Note that this method does not work on
55
+ # ruby 1.8.7, you will have to override it if you are using ruby 1.8.7.
56
+ def create_uuid
57
+ SecureRandom.uuid
58
+ end
59
+
60
+ # If the object has accessor methods for the uuid field, and the uuid
61
+ # value is nil or overwriting it is allowed, set the uuid.
62
+ def set_uuid(uuid=create_uuid)
63
+ field = model.uuid_field
64
+ meth = :"#{field}="
65
+ if respond_to?(field) && respond_to?(meth) && (model.uuid_overwrite? || get_column_value(field).nil?)
66
+ set_column_value(meth, uuid)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -3,7 +3,7 @@ module Sequel
3
3
  MAJOR = 4
4
4
  # The minor version of Sequel. Bumped for every non-patch level
5
5
  # release, generally around once a month.
6
- MINOR = 28
6
+ MINOR = 29
7
7
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
8
8
  # releases that fix regressions from previous versions.
9
9
  TINY = 0
@@ -987,7 +987,7 @@ describe "A PostgreSQL database" do
987
987
  t2 = "ruby sequel " * 1000
988
988
  @db[:posts].insert(:title=>t1)
989
989
  @db[:posts].insert(:title=>t2)
990
- @db[:posts].full_text_search(:title, 'ruby & sequel', :rank=>true).select_map(:title).must_equal [t1, t2]
990
+ @db[:posts].full_text_search(:title, 'ruby & sequel', :rank=>true).select_map(:title).must_equal [t2, t1]
991
991
  end
992
992
 
993
993
  it "should support spatial indexes" do
@@ -614,6 +614,17 @@ describe "Database#table_exists?" do
614
614
  db.table_exists?(:b).must_equal true
615
615
  db.table_exists?(:c).must_equal true
616
616
  end
617
+
618
+ it "should use a savepoint if inside a transaction" do
619
+ db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
620
+ def db.supports_savepoints?; true end
621
+ db.transaction do
622
+ db.table_exists?(:a).must_equal false
623
+ end
624
+ db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "SELECT NULL AS nil FROM a LIMIT 1", "ROLLBACK TO SAVEPOINT autopoint_1", "COMMIT"]
625
+ db.table_exists?(:b).must_equal true
626
+ db.table_exists?(:c).must_equal true
627
+ end
617
628
  end
618
629
 
619
630
  DatabaseTransactionSpecs = shared_description do
@@ -964,6 +975,30 @@ describe "Database#transaction with savepoint support" do
964
975
 
965
976
  include DatabaseTransactionSpecs
966
977
 
978
+ it "should support :retry_on option for automatically retrying transactions when using :savepoint option" do
979
+ a = []
980
+ @db.transaction do
981
+ @db.transaction(:retry_on=>Sequel::SerializationFailure, :savepoint=>true) do
982
+ a << 1
983
+ raise Sequel::SerializationFailure if a.length == 1
984
+ end
985
+ end
986
+ @db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
987
+ a.must_equal [1, 1]
988
+ end
989
+
990
+ it "should support :retry_on option for automatically retrying transactions inside an :auto_savepoint transaction" do
991
+ a = []
992
+ @db.transaction(:auto_savepoint=>true) do
993
+ @db.transaction(:retry_on=>Sequel::SerializationFailure) do
994
+ a << 1
995
+ raise Sequel::SerializationFailure if a.length == 1
996
+ end
997
+ end
998
+ @db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
999
+ a.must_equal [1, 1]
1000
+ end
1001
+
967
1002
  it "should support after_commit inside savepoints" do
968
1003
  @db.transaction do
969
1004
  @db.after_commit{@db.execute('foo')}
@@ -65,6 +65,23 @@ describe "date_arithmetic extension" do
65
65
  end
66
66
  end
67
67
 
68
+ it "should use existing method" do
69
+ db = Sequel.mock
70
+ db.extend_datasets do
71
+ def date_add_sql_append(sql, da)
72
+ interval = ''
73
+ each_valid_interval_unit(da.interval, Sequel::SQL::DateAdd::DatasetMethods::DEF_DURATION_UNITS) do |value, sql_unit|
74
+ interval << "#{value} #{sql_unit} "
75
+ end
76
+ literal_append(sql, Sequel.function(:da, da.expr, interval))
77
+ end
78
+ end
79
+ db.extension :date_arithmetic
80
+ db.literal(Sequel.date_add(:a, @h0)).must_equal "da(a, '')"
81
+ db.literal(Sequel.date_add(:a, @h1)).must_equal "da(a, '1 days ')"
82
+ db.literal(Sequel.date_add(:a, @h2)).must_equal "da(a, '1 years 1 months 1 days 1 hours 1 minutes 1 seconds ')"
83
+ end
84
+
68
85
  it "should correctly literalize on Postgres" do
69
86
  db = dbf.call(:postgres)
70
87
  db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS timestamp)"
@@ -43,6 +43,13 @@ describe "Sequel::Plugins::JsonSerializer" do
43
43
  Artist.from_json(Artist.load(:name=>Date.today).to_json).must_equal Artist.load(:name=>Date.today)
44
44
  end
45
45
 
46
+ it "should support setting json_serializer_opts on models" do
47
+ @artist.json_serializer_opts(:only=>:name)
48
+ Sequel.parse_json([@artist].to_json).must_equal [{'name'=>@artist.name}]
49
+ @artist.json_serializer_opts(:include=>{:albums=>{:only=>:name}})
50
+ Sequel.parse_json([@artist].to_json).must_equal [{'name'=>@artist.name, 'albums'=>[{'name'=>@album.name}]}]
51
+ end
52
+
46
53
  it "should handle the :only option" do
47
54
  Artist.from_json(@artist.to_json(:only=>:name)).must_equal Artist.load(:name=>@artist.name)
48
55
  Album.from_json(@album.to_json(:only=>[:id, :name])).must_equal Album.load(:id=>@album.id, :name=>@album.name)
@@ -0,0 +1,106 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::Uuid" do
4
+ before do
5
+ uuid = @uuid = '57308544-4e83-47b8-b87f-6f68b987f4f9'
6
+ @alt_uuid = 'd5d1ec46-5e8e-4a7b-adc9-50e76b819e19'
7
+ dc = Object.new
8
+ @c = Class.new(Sequel::Model(:t))
9
+ @c.class_eval do
10
+ columns :id, :uuid
11
+ plugin :uuid
12
+ def _save_refresh(*) end
13
+ define_method(:create_uuid) do
14
+ uuid
15
+ end
16
+ db.reset
17
+ end
18
+ @c.dataset.autoid = nil
19
+ end
20
+
21
+ it "should handle validations on the uuid field for new objects" do
22
+ @c.plugin :uuid, :force=>true
23
+ o = @c.new
24
+ def o.validate
25
+ errors.add(model.uuid_field, 'not present') unless send(model.uuid_field)
26
+ end
27
+ o.valid?.must_equal true
28
+ end
29
+
30
+ it "should set uuid field when skipping validations" do
31
+ @c.plugin :uuid
32
+ @c.new.save(:validate=>false)
33
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
34
+ end
35
+
36
+ it "should set the uuid field on creation" do
37
+ o = @c.create
38
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
39
+ o.uuid.must_equal @uuid
40
+ end
41
+
42
+ if RUBY_VERSION >= '1.9'
43
+ it "should allow specifying the uuid field via the :field option" do
44
+ c = Class.new(Sequel::Model(:t))
45
+ c.class_eval do
46
+ columns :id, :u
47
+ plugin :uuid, :field=>:u
48
+ def _save_refresh(*) end
49
+ end
50
+ o = c.create
51
+ c.db.sqls.first.must_match(/INSERT INTO t \(u\) VALUES \('[-0-9a-f]+'\)/)
52
+ o.u.must_match /[-0-9a-f]+/
53
+ end
54
+ end
55
+
56
+ it "should not raise an error if the model doesn't have the uuid column" do
57
+ @c.columns :id, :x
58
+ @c.send(:undef_method, :uuid)
59
+ @c.create(:x=>2)
60
+ @c.load(:id=>1, :x=>2).save
61
+ @c.db.sqls.must_equal ["INSERT INTO t (x) VALUES (2)", "UPDATE t SET x = 2 WHERE (id = 1)"]
62
+ end
63
+
64
+ it "should not overwrite an existing uuid value" do
65
+ o = @c.create(:uuid=>@alt_uuid)
66
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@alt_uuid}')"]
67
+ o.uuid.must_equal @alt_uuid
68
+ end
69
+
70
+ it "should overwrite an existing uuid if the :force option is used" do
71
+ @c.plugin :uuid, :force=>true
72
+ o = @c.create(:uuid=>@alt_uuid)
73
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
74
+ o.uuid.must_equal @uuid
75
+ end
76
+
77
+ it "should have uuid_field give the uuid field" do
78
+ @c.uuid_field.must_equal :uuid
79
+ @c.plugin :uuid, :field=>:u
80
+ @c.uuid_field.must_equal :u
81
+ end
82
+
83
+ it "should have uuid_overwrite? give the whether to overwrite an existing uuid" do
84
+ @c.uuid_overwrite?.must_equal false
85
+ @c.plugin :uuid, :force=>true
86
+ @c.uuid_overwrite?.must_equal true
87
+ end
88
+
89
+ it "should work with subclasses" do
90
+ c = Class.new(@c)
91
+ o = c.create
92
+ o.uuid.must_equal @uuid
93
+ c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
94
+ c.create(:uuid=>@alt_uuid).uuid.must_equal @alt_uuid
95
+
96
+ c.class_eval do
97
+ columns :id, :u
98
+ plugin :uuid, :field=>:u, :force=>true
99
+ end
100
+ c2 = Class.new(c)
101
+ c2.db.reset
102
+ o = c2.create
103
+ o.u.must_equal @uuid
104
+ c2.db.sqls.first.must_match(/INSERT INTO t \([u]\) VALUES \('#{@uuid}'\)/)
105
+ end
106
+ end
@@ -355,13 +355,13 @@ describe "Bound Argument Types" do
355
355
  @ds.literal(@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>fract_time)[:t]).must_equal @ds.literal(fract_time)
356
356
  end
357
357
 
358
- cspecify "should handle blob type", [:odbc], [:oracle] do
358
+ cspecify "should handle blob type", [:odbc] do
359
359
  @ds.delete
360
360
  @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>@vs[:file])
361
361
  @ds.get(:file).must_equal @vs[:file]
362
362
  end
363
363
 
364
- cspecify "should handle blob type with special characters", [:odbc], [:oracle] do
364
+ cspecify "should handle blob type with special characters", [:odbc] do
365
365
  @ds.delete
366
366
  blob = Sequel.blob("\"'[]`a0 ")
367
367
  @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>blob)
@@ -374,7 +374,7 @@ describe "Bound Argument Types" do
374
374
  @ds.get(:file).must_equal nil
375
375
  end
376
376
 
377
- cspecify "should handle blob type with embedded zeros", [:odbc], [:oracle] do
377
+ cspecify "should handle blob type with embedded zeros", [:odbc] do
378
378
  zero_blob = Sequel::SQL::Blob.new("a\0"*100)
379
379
  @ds.delete
380
380
  @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>zero_blob)
@@ -582,7 +582,7 @@ describe "Database schema modifiers" do
582
582
  @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
583
583
  @ds.columns!.must_equal [:id]
584
584
  @ds.insert(:id=>'20')
585
- @ds.all.must_equal [{:id=>"10"}, {:id=>"20"}]
585
+ @ds.order(:id).all.must_equal [{:id=>"10"}, {:id=>"20"}]
586
586
  end
587
587
 
588
588
  cspecify "should set column types without modifying NULL/NOT NULL", [:jdbc, :db2], [:db2], :oracle, :derby do
@@ -84,6 +84,28 @@ describe "Database transactions" do
84
84
  end
85
85
 
86
86
  if DB.supports_savepoints?
87
+ it "should handle table_exists? failures inside transactions" do
88
+ @db.transaction do
89
+ @d << {:name => '1'}
90
+ @db.table_exists?(:asadf098asd9asd98sa).must_equal false
91
+ @d << {:name => '2'}
92
+ end
93
+ @d.select_order_map(:name).must_equal %w'1 2'
94
+ end
95
+
96
+ it "should handle table_exists? failures inside savepoints" do
97
+ @db.transaction do
98
+ @d << {:name => '1'}
99
+ @db.transaction(:savepoint=>true) do
100
+ @d << {:name => '2'}
101
+ @db.table_exists?(:asadf098asd9asd98sa).must_equal false
102
+ @d << {:name => '3'}
103
+ end
104
+ @d << {:name => '4'}
105
+ end
106
+ @d.select_order_map(:name).must_equal %w'1 2 3 4'
107
+ end
108
+
87
109
  it "should support nested transactions through savepoints using the savepoint option" do
88
110
  @db.transaction do
89
111
  @d << {:name => '1'}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.28.0
4
+ version: 4.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-02 00:00:00.000000000 Z
11
+ date: 2015-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -229,6 +229,7 @@ extra_rdoc_files:
229
229
  - doc/release_notes/4.26.0.txt
230
230
  - doc/release_notes/4.27.0.txt
231
231
  - doc/release_notes/4.28.0.txt
232
+ - doc/release_notes/4.29.0.txt
232
233
  files:
233
234
  - CHANGELOG
234
235
  - MIT-LICENSE
@@ -345,6 +346,7 @@ files:
345
346
  - doc/release_notes/4.26.0.txt
346
347
  - doc/release_notes/4.27.0.txt
347
348
  - doc/release_notes/4.28.0.txt
349
+ - doc/release_notes/4.29.0.txt
348
350
  - doc/release_notes/4.3.0.txt
349
351
  - doc/release_notes/4.4.0.txt
350
352
  - doc/release_notes/4.5.0.txt
@@ -598,6 +600,7 @@ files:
598
600
  - lib/sequel/plugins/update_or_create.rb
599
601
  - lib/sequel/plugins/update_primary_key.rb
600
602
  - lib/sequel/plugins/update_refresh.rb
603
+ - lib/sequel/plugins/uuid.rb
601
604
  - lib/sequel/plugins/validate_associated.rb
602
605
  - lib/sequel/plugins/validation_class_methods.rb
603
606
  - lib/sequel/plugins/validation_helpers.rb
@@ -755,6 +758,7 @@ files:
755
758
  - spec/extensions/update_or_create_spec.rb
756
759
  - spec/extensions/update_primary_key_spec.rb
757
760
  - spec/extensions/update_refresh_spec.rb
761
+ - spec/extensions/uuid_spec.rb
758
762
  - spec/extensions/validate_associated_spec.rb
759
763
  - spec/extensions/validation_class_methods_spec.rb
760
764
  - spec/extensions/validation_helpers_spec.rb