simply_stored 0.1.8 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,7 @@ module SimplyStored
46
46
  owner_clazz.class_eval do
47
47
  attr_reader "#{name}_id"
48
48
  attr_accessor "#{name}_id_was"
49
+ property "#{name}_id"
49
50
 
50
51
  define_method name do |*args|
51
52
  options = args.last.is_a?(Hash) ? args.last : {}
@@ -54,13 +55,13 @@ module SimplyStored
54
55
  with_deleted = options[:with_deleted] || false
55
56
 
56
57
  return instance_variable_get("@#{name}") unless instance_variable_get("@#{name}").nil? or forced_reload
57
- instance_variable_set("@#{name}", send("#{name}_id") ? Object.const_get(item_class_name).find(send("#{name}_id"), :with_deleted => with_deleted) : nil)
58
+ instance_variable_set("@#{name}", send("#{name}_id").present? ? Object.const_get(item_class_name).find(send("#{name}_id"), :with_deleted => with_deleted) : nil)
58
59
  end
59
60
 
60
61
  define_method "#{name}=" do |value|
61
62
  klass = self.class.get_class_from_name(name)
62
63
  raise ArgumentError, "expected #{klass} got #{value.class}" unless value.nil? || value.is_a?(klass)
63
-
64
+
64
65
  instance_variable_set("@#{name}", value)
65
66
  if value.nil?
66
67
  instance_variable_set("@#{name}_id", nil)
@@ -26,8 +26,24 @@ module SimplyStored
26
26
  end
27
27
  ret
28
28
  end
29
+
30
+ def save!(*args)
31
+ super
32
+ save_attachments
33
+ end
34
+
35
+ def delete(*args)
36
+ delete_attachments
37
+ super
38
+ end
39
+
40
+ def destroy(*args)
41
+ delete_attachments
42
+ super
43
+ end
29
44
 
30
45
  def save_attachments
46
+ return unless id.present?
31
47
  if @_s3_attachments
32
48
  @_s3_attachments.each do |name, attachment|
33
49
  if attachment[:dirty]
@@ -38,6 +54,16 @@ module SimplyStored
38
54
  end
39
55
  end
40
56
  end
57
+
58
+ def delete_attachments
59
+ return unless id.present?
60
+ (@_s3_attachments || {}).each do |name, attachment|
61
+ if _s3_options[name][:after_delete] == :delete
62
+ key = s3_bucket(name).key(s3_attachment_key(name), true)
63
+ key.delete
64
+ end
65
+ end
66
+ end
41
67
 
42
68
  def s3_attachment_key(name)
43
69
  "#{self.class.name.tableize}/#{name}/#{id}"
@@ -60,7 +86,8 @@ module SimplyStored
60
86
  :permissions => 'private',
61
87
  :ssl => true,
62
88
  :location => :us, # use :eu for European buckets
63
- :ca_file => nil # point to CA file for SSL certificate verification
89
+ :ca_file => nil, # point to CA file for SSL certificate verification
90
+ :after_delete => :nothing # or :delete to delete the item on S3 after it is deleted in the DB
64
91
  }.update(options)
65
92
  self._s3_options ||= {}
66
93
  self._s3_options[name] = options
@@ -329,6 +329,15 @@ class CouchTest < Test::Unit::TestCase
329
329
  assert_equal user.id, post.user_id
330
330
  end
331
331
 
332
+ should "set also the foreign key id to nil if setting the referencing object to nil" do
333
+ user = User.create(:title => "Mr.")
334
+ post = Post.create(:user => user)
335
+ post.user = nil
336
+ post.save!
337
+ assert_nil post.reload.user
338
+ assert_nil post.reload.user_id
339
+ end
340
+
332
341
  should "fetch the object from the database when requested through the getter" do
333
342
  user = User.create(:title => "Mr.")
334
343
  post = Post.create(:user => user)
@@ -427,6 +436,15 @@ class CouchTest < Test::Unit::TestCase
427
436
  post.save!
428
437
  assert !post.user_changed?
429
438
  end
439
+
440
+ should "handle a foreign_key of '' as nil" do
441
+ post = Post.create
442
+ post.user_id = ''
443
+
444
+ assert_nothing_raised do
445
+ assert_nil post.user
446
+ end
447
+ end
430
448
  end
431
449
 
432
450
  context "with has_many" do
@@ -1040,6 +1058,25 @@ class CouchTest < Test::Unit::TestCase
1040
1058
  assert_equal "Hostess Masteress", user.name
1041
1059
  end
1042
1060
 
1061
+ should "remove attributes that are no longer in the database" do
1062
+ user = User.create(:title => "Mr.", :name => "Host Master")
1063
+ assert_not_nil user.name
1064
+ same_user_in_different_thread = User.find(user.id)
1065
+ same_user_in_different_thread.name = nil
1066
+ same_user_in_different_thread.save!
1067
+ assert_nil user.reload.name
1068
+ end
1069
+
1070
+ should "also remove foreign key attributes that are no longer in the database" do
1071
+ user = User.create(:title => "Mr.", :name => "Host Master")
1072
+ post = Post.create(:user => user)
1073
+ assert_not_nil post.user_id
1074
+ same_post_in_different_thread = Post.find(post.id)
1075
+ same_post_in_different_thread.user = nil
1076
+ same_post_in_different_thread.save!
1077
+ assert_nil post.reload.user_id
1078
+ end
1079
+
1043
1080
  should "not be dirty after reloading" do
1044
1081
  user = User.create(:title => "Mr.", :name => "Host Master")
1045
1082
  user2 = User.find(user.id)
@@ -1109,6 +1146,12 @@ class CouchTest < Test::Unit::TestCase
1109
1146
  @bucket.expects(:put).with(anything, "Yay! It logged!", {}, anything)
1110
1147
  @log_item.save
1111
1148
  end
1149
+
1150
+ should "also upload on save!" do
1151
+ @log_item.log_data = "Yay! It logged!"
1152
+ @bucket.expects(:put).with(anything, "Yay! It logged!", {}, anything)
1153
+ @log_item.save!
1154
+ end
1112
1155
 
1113
1156
  should "use the specified bucket" do
1114
1157
  @log_item.log_data = "Yay! It logged!"
@@ -1261,6 +1304,27 @@ class CouchTest < Test::Unit::TestCase
1261
1304
  assert_equal "Yay!", @log_item.log_data
1262
1305
  end
1263
1306
  end
1307
+
1308
+ context "when deleting" do
1309
+ setup do
1310
+ CouchLogItem._s3_options[:log_data][:after_delete] = :nothing
1311
+ @log_item.log_data = 'Yatzzee'
1312
+ @log_item.save
1313
+ end
1314
+
1315
+ should "do nothing to S3" do
1316
+ @bucket.expects(:key).never
1317
+ @log_item.delete
1318
+ end
1319
+
1320
+ should "also delete on S3 if configured so" do
1321
+ CouchLogItem._s3_options[:log_data][:after_delete] = :delete
1322
+ s3_key = mock(:delete => true)
1323
+ @bucket.expects(:key).with(@log_item.s3_attachment_key('log_data'), true).returns(s3_key)
1324
+ @log_item.delete
1325
+ end
1326
+
1327
+ end
1264
1328
  end
1265
1329
 
1266
1330
  context "when using soft deletable" do
@@ -1170,6 +1170,7 @@ class SimplyStoredTest < Test::Unit::TestCase
1170
1170
  context "with s3 interaction" do
1171
1171
  setup do
1172
1172
  LogItem.instance_variable_set(:@_s3_connection, nil)
1173
+ LogItem._s3_options[:log_data][:ca_file] = nil
1173
1174
 
1174
1175
  bucket = stub(:bckt) do
1175
1176
  stubs(:put).returns(true)
@@ -1189,7 +1190,7 @@ class SimplyStoredTest < Test::Unit::TestCase
1189
1190
  context "when saving the attachment" do
1190
1191
  should "fetch the collection" do
1191
1192
  @log_item.log_data = "Yay! It logged!"
1192
- RightAws::S3.expects(:new).with('abcdef', 'secret!', :multi_thread => true).returns(@s3)
1193
+ RightAws::S3.expects(:new).with('abcdef', 'secret!', :multi_thread => true, :ca_file => nil).returns(@s3)
1193
1194
  @log_item.save
1194
1195
  end
1195
1196
 
@@ -1198,7 +1199,7 @@ class SimplyStoredTest < Test::Unit::TestCase
1198
1199
  @bucket.expects(:put).with(anything, "Yay! It logged!", {}, anything)
1199
1200
  @log_item.save
1200
1201
  end
1201
-
1202
+
1202
1203
  should "use the specified bucket" do
1203
1204
  @log_item.log_data = "Yay! It logged!"
1204
1205
  LogItem._s3_options[:log_data][:bucket] = 'mybucket'
@@ -1211,7 +1212,17 @@ class SimplyStoredTest < Test::Unit::TestCase
1211
1212
  LogItem._s3_options[:log_data][:bucket] = 'mybucket'
1212
1213
 
1213
1214
  @s3.expects(:bucket).with('mybucket').returns(nil)
1214
- @s3.expects(:bucket).with('mybucket', true, 'private').returns(@bucket)
1215
+ @s3.expects(:bucket).with('mybucket', true, 'private', :location => nil).returns(@bucket)
1216
+ @log_item.save
1217
+ end
1218
+
1219
+ should "accept :us location option but not set it in RightAWS::S3" do
1220
+ @log_item.log_data = "Yay! log me"
1221
+ LogItem._s3_options[:log_data][:bucket] = 'mybucket'
1222
+ LogItem._s3_options[:log_data][:location] = :us
1223
+
1224
+ @s3.expects(:bucket).with('mybucket').returns(nil)
1225
+ @s3.expects(:bucket).with('mybucket', true, 'private', :location => nil).returns(@bucket)
1215
1226
  @log_item.save
1216
1227
  end
1217
1228
 
@@ -1220,7 +1231,7 @@ class SimplyStoredTest < Test::Unit::TestCase
1220
1231
  LogItem._s3_options[:log_data][:bucket] = 'mybucket'
1221
1232
 
1222
1233
  @s3.expects(:bucket).with('mybucket').returns(nil)
1223
- @s3.expects(:bucket).with('mybucket', true, 'private').raises(RightAws::AwsError, 'BucketAlreadyExists: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again')
1234
+ @s3.expects(:bucket).with('mybucket', true, 'private', :location => nil).raises(RightAws::AwsError, 'BucketAlreadyExists: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again')
1224
1235
 
1225
1236
  assert_raise(ArgumentError) do
1226
1237
  @log_item.save
@@ -1295,6 +1306,8 @@ class SimplyStoredTest < Test::Unit::TestCase
1295
1306
  end
1296
1307
 
1297
1308
  should "add a short-lived access key for private attachments" do
1309
+ @log_item._s3_options[:log_data][:bucket] = 'bucket-for-monsieur'
1310
+ @log_item._s3_options[:log_data][:location] = :us
1298
1311
  @log_item._s3_options[:log_data][:permissions] = 'private'
1299
1312
  @log_item.save
1300
1313
  assert @log_item.log_data_url.include?("https://bucket-for-monsieur.s3.amazonaws.com:443/#{@log_item.s3_attachment_key(:log_data)}")
@@ -1329,6 +1342,28 @@ class SimplyStoredTest < Test::Unit::TestCase
1329
1342
  assert_equal "Yay!", @log_item.log_data
1330
1343
  end
1331
1344
  end
1345
+
1346
+ context "when deleting" do
1347
+ setup do
1348
+ LogItem._s3_options[:log_data][:after_delete] = :nothing
1349
+ @log_item.log_data = 'Yatzzee'
1350
+ @log_item.save
1351
+ end
1352
+
1353
+ should "do nothing to S3" do
1354
+ @bucket.expects(:key).never
1355
+ @log_item.delete
1356
+ end
1357
+
1358
+ should "also delete on S3 if configured so" do
1359
+ LogItem._s3_options[:log_data][:after_delete] = :delete
1360
+ s3_key = mock(:delete => true)
1361
+ @bucket.expects(:key).with(@log_item.s3_attachment_key('log_data'), true).returns(s3_key)
1362
+ @log_item.delete
1363
+ end
1364
+
1365
+ end
1366
+
1332
1367
  end
1333
1368
  end
1334
1369
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simply_stored
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias Meyer, Jonathan Weiss
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-06 00:00:00 +01:00
12
+ date: 2010-01-20 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency