simply_stored 0.1.8 → 0.1.12

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