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.
|
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-
|
12
|
+
date: 2010-01-20 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|