tinkit 0.0.0
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.
- data/LICENSE +176 -0
- data/README +11 -0
- data/Rakefile +75 -0
- data/lib/glue_envs/couchrest/couchrest_attachment_handler.rb +260 -0
- data/lib/glue_envs/couchrest/couchrest_files_mgr.rb +198 -0
- data/lib/glue_envs/couchrest_glue_env.rb +536 -0
- data/lib/glue_envs/files_mgr_base.rb +51 -0
- data/lib/glue_envs/filesystem/filesystem_files_mgr.rb +187 -0
- data/lib/glue_envs/filesystem_glue_env.rb +395 -0
- data/lib/glue_envs/mysql/mysql_files_mgr.rb +175 -0
- data/lib/glue_envs/mysql_glue_env.rb +428 -0
- data/lib/glue_envs/sdb_s3/sdb_s3_files_mgr.rb +314 -0
- data/lib/glue_envs/sdb_s3_glue_env.rb +248 -0
- data/lib/helpers/camel.rb +21 -0
- data/lib/helpers/filesystem_helpers.rb +27 -0
- data/lib/helpers/hash_helpers.rb +74 -0
- data/lib/helpers/log_helper.rb +34 -0
- data/lib/helpers/mime_types_new.rb +126 -0
- data/lib/helpers/old_more_open_struct.rb +28 -0
- data/lib/helpers/require_helper.rb +45 -0
- data/lib/helpers/tk_escape.rb +17 -0
- data/lib/midas/bufs_data_structure.rb +84 -0
- data/lib/midas/node_element_operations.rb +264 -0
- data/lib/tinkit.rb +38 -0
- data/lib/tinkit_base_node.rb +733 -0
- data/lib/tinkit_node_factory.rb +47 -0
- data/spec/couchrest_files_mgr_spec.rb +551 -0
- data/spec/couchrest_glue_spec.rb +246 -0
- data/spec/filesystem_files_mgr_spec.rb +236 -0
- data/spec/filesystem_glue_spec.rb +243 -0
- data/spec/filesystem_helpers_spec.rb +42 -0
- data/spec/helpers/bufs_node_builder.rb +17 -0
- data/spec/helpers/bufs_sample_dataset.rb +160 -0
- data/spec/helpers/bufs_test_environments.rb +81 -0
- data/spec/helpers/tmp_view_cleaner.rb +15 -0
- data/spec/lib_helpers/tk_escape_spec.rb +45 -0
- data/spec/mysql_files_mgr_spec.rb +250 -0
- data/spec/mysql_glue_spec.rb +214 -0
- data/spec/node_element_operations_spec.rb +392 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec1.rb +82 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec2.rb +68 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec3.rb +80 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec4.rb +110 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec5.rb +84 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec6.rb +83 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec7.rb +101 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec8.rb +92 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec_all.rb +266 -0
- data/spec/sdb_s3_glue_spec.rb +230 -0
- data/spec/tinkit_node_factory_spec.rb +1108 -0
- metadata +114 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
#require helper for cleaner require statements
|
2
|
+
require File.join(File.dirname(__FILE__), '/helpers/require_helper')
|
3
|
+
|
4
|
+
require Tinkit.lib 'tinkit_base_node'
|
5
|
+
require Tinkit.helpers 'log_helper'
|
6
|
+
|
7
|
+
class TinkitNodeFactory
|
8
|
+
#Set Logger
|
9
|
+
@@log = TinkitLog.set(self.name, :debug)
|
10
|
+
|
11
|
+
def self.make(node_env)
|
12
|
+
TinkitLog.log_raise "No Node Environment provided" unless node_env
|
13
|
+
TinkitLog.log_raise "Empty Node Environment provided" if node_env.empty?
|
14
|
+
TinkitLog.log_raise "Malformed Node Environment" unless node_env.respond_to?(:keys)
|
15
|
+
TinkitLog.log_raise "Malformed Node Environment" unless node_env.keys.include? :persist_model
|
16
|
+
|
17
|
+
|
18
|
+
neo_env = node_env[:data_model] || {}
|
19
|
+
|
20
|
+
neo = NodeElementOperations.new(neo_env)
|
21
|
+
data_model_bindings = {:key_fields => neo.key_fields,
|
22
|
+
#:data_ops_set => neo.field_op_set_sym,
|
23
|
+
:views => neo.views}
|
24
|
+
|
25
|
+
#TODO: Make setting the environment thread safe
|
26
|
+
class_environment = node_env[:persist_model]
|
27
|
+
user_doc_class_name = node_env[:node_class_id]
|
28
|
+
|
29
|
+
#Security TODO: remove spaces and other
|
30
|
+
|
31
|
+
#---- Dynamic Class Definitions ----
|
32
|
+
dyn_user_class_def = "class #{user_doc_class_name} < TinkitBaseNode
|
33
|
+
|
34
|
+
class << self; attr_accessor :user_attachClass, end
|
35
|
+
|
36
|
+
end"
|
37
|
+
|
38
|
+
TinkitNodeFactory.class_eval(dyn_user_class_def)
|
39
|
+
docClass = TinkitNodeFactory.const_get(user_doc_class_name)
|
40
|
+
|
41
|
+
docClass.data_struc = neo
|
42
|
+
|
43
|
+
#TODO: Streamline the paramaters (maybe one env paramater?)
|
44
|
+
docClass.set_environment(class_environment, data_model_bindings)
|
45
|
+
docClass
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,551 @@
|
|
1
|
+
#require helper for cleaner require statements
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/helpers/require_helper')
|
3
|
+
|
4
|
+
require 'spec'
|
5
|
+
require 'couchrest'
|
6
|
+
|
7
|
+
require Tinkit.glue 'couchrest/couchrest_files_mgr'
|
8
|
+
|
9
|
+
include CouchrestInterface
|
10
|
+
|
11
|
+
FileMgrTestDb = CouchRest.database!("http://127.0.0.1:5984/couchrest_file_mgr_test")
|
12
|
+
FileMgrTestDb.compact!
|
13
|
+
|
14
|
+
GlueEnvMock = Struct.new(:model_key, :user_id, :moab_data)
|
15
|
+
|
16
|
+
class MockAttachClass < CouchrestAttachment
|
17
|
+
use_database FileMgrTestDb
|
18
|
+
|
19
|
+
def self.namespace
|
20
|
+
FileMgrTestDb
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class MockNode
|
25
|
+
attr_accessor :_id, :my_GlueEnv, :_model_metadata, :attachment_doc_id
|
26
|
+
|
27
|
+
def initialize(id, glue_env, model_md)
|
28
|
+
@_id = id
|
29
|
+
@my_GlueEnv = glue_env
|
30
|
+
@_model_metadata = model_md
|
31
|
+
@atts = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def __set_userdata_key(node_att_doc_id, db_att_doc_id)
|
35
|
+
@attachment_doc_id = db_att_doc_id
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe FilesMgr, "Setup and intialization" do
|
41
|
+
|
42
|
+
before(:all) do
|
43
|
+
moab_data = {:attachClass => MockAttachClass, :db => FileMgrTestDb }
|
44
|
+
@glue_env_mock = GlueEnvMock.new("_id", "couchrest_user", moab_data)
|
45
|
+
@node_key = :_id
|
46
|
+
|
47
|
+
file1_data = "Example File1\nJust some text"
|
48
|
+
file2_data = "Example File2\nJust some more text"
|
49
|
+
file1_fname = "/tmp/example_file1.txt"
|
50
|
+
file2_fname = "/tmp/example_file2.txt"
|
51
|
+
files = {file1_fname => file1_data, file2_fname => file2_data}
|
52
|
+
files.each do |fname, data|
|
53
|
+
File.open(fname, 'w'){|f| f.write(data)}
|
54
|
+
end
|
55
|
+
@file_datas = [{:src_filename => file1_fname}, {:src_filename => file2_fname}]
|
56
|
+
@node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should initialize" do
|
60
|
+
node_key_value = @node1_data[@node_key]
|
61
|
+
attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
|
62
|
+
att_class_base_name = "MoabAttachmentHandler"
|
63
|
+
user_id = @glue_env_mock.user_id
|
64
|
+
attach_handler.attachment_doc_class.should == @glue_env_mock.moab_data[:attachClass]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe FilesMgr, "Basic Operations" do
|
69
|
+
before(:all) do
|
70
|
+
#@user_datastore_location = "/tmp/datastore_location"
|
71
|
+
@file1_fname = "/tmp/example_file1.txt"
|
72
|
+
@file2_fname = "/tmp/example_file2.txt"
|
73
|
+
f1_bname = File.basename(@file1_fname)
|
74
|
+
f2_bname = File.basename(@file2_fname)
|
75
|
+
@file_stored_data = { f1_bname => File.open(@file1_fname, 'rb'){|f| f.read},
|
76
|
+
f2_bname =>File.open(@file2_fname, 'rb'){|f| f.read} }
|
77
|
+
|
78
|
+
@mock_key = :_id
|
79
|
+
#@nodeMockClass = Struct.new(@mock_key, :my_GlueEnv, :"_model_metadata")
|
80
|
+
|
81
|
+
moab_data = {:attachClass => MockAttachClass, :db => FileMgrTestDb }
|
82
|
+
@glue_env_mock = GlueEnvMock.new(@mock_key,
|
83
|
+
"couchrest_user", moab_data)
|
84
|
+
|
85
|
+
@file_datas = [{:src_filename => @file1_fname}, {:src_filename => @file2_fname}]
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
before(:each) do
|
90
|
+
@node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
|
91
|
+
model_metadata = {:_id => 'spec_test1'}
|
92
|
+
@node_mock = MockNode.new(@node1_data[@mock_key],
|
93
|
+
@glue_env_mock,
|
94
|
+
model_metadata)
|
95
|
+
|
96
|
+
node_key_value = @node1_data[@mock_key]
|
97
|
+
@attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
|
98
|
+
#@attach_handler.subtract_files(nil, :all)
|
99
|
+
end
|
100
|
+
|
101
|
+
after(:all) do
|
102
|
+
FileMgrTestDb.delete!
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should add and retrieve files" do
|
106
|
+
node = @node_mock
|
107
|
+
|
108
|
+
@file_datas.each do |file_data|
|
109
|
+
file_basename = File.basename(file_data[:src_filename])
|
110
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
111
|
+
data.should be_nil
|
112
|
+
end
|
113
|
+
|
114
|
+
#Add the Files
|
115
|
+
@attach_handler.add(node, @file_datas)
|
116
|
+
|
117
|
+
#Get the files and verify data
|
118
|
+
@file_datas.each do |file_data|
|
119
|
+
file_basename = File.basename(file_data[:src_filename])
|
120
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
121
|
+
data.should == @file_stored_data[file_basename]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should list attachment files" do
|
126
|
+
files = @attach_handler.list(@node_mock)
|
127
|
+
files.sort.should == @file_stored_data.keys.sort
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should list metadata" do
|
131
|
+
md = @attach_handler.get_attachments_metadata(@node_mock)
|
132
|
+
md.should_not == nil
|
133
|
+
@file_datas.each do |file_data|
|
134
|
+
file_basename = File.basename(file_data[:src_filename])
|
135
|
+
each_md = md[file_basename]
|
136
|
+
each_md.should_not == nil
|
137
|
+
each_md.keys.should include :content_type
|
138
|
+
each_md.keys.should include :file_modified
|
139
|
+
|
140
|
+
file_basename = File.basename(file_data[:src_filename])
|
141
|
+
md[file_basename][:content_type].should =~ /^text\/plain/
|
142
|
+
time_str = md[file_basename][:file_modified]
|
143
|
+
Time.parse(time_str).should >= Time.now - 2 #should have been modified less than 2 seconds ago
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should be well behaved adding more files" do
|
148
|
+
node = @node_mock
|
149
|
+
|
150
|
+
#Get the original files and verify data
|
151
|
+
@file_datas.each do |file_data|
|
152
|
+
file_basename = File.basename(file_data[:src_filename])
|
153
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
154
|
+
data.should == @file_stored_data[file_basename]
|
155
|
+
end
|
156
|
+
|
157
|
+
#create some more files
|
158
|
+
file1_data = "Example File1\nNEW!! text"
|
159
|
+
file3_data = "Example File3\nYet more text"
|
160
|
+
file4_data = "Example File4\nand more text"
|
161
|
+
file3_fname = "/tmp/example_file3.txt"
|
162
|
+
file4_fname = "/tmp/example_file4.txt"
|
163
|
+
files = {@file1_fname => file1_data, file3_fname => file3_data, file4_fname => file4_data}
|
164
|
+
files.each do |fname, data|
|
165
|
+
File.open(fname, 'w'){|f| f.write(data)}
|
166
|
+
end
|
167
|
+
file1_data.should == File.open(@file1_fname){|f| f.read}
|
168
|
+
|
169
|
+
@file_datas2 = [{:src_filename => @file1_fname},
|
170
|
+
{:src_filename => file3_fname},
|
171
|
+
{:src_filename => file4_fname}]
|
172
|
+
|
173
|
+
|
174
|
+
#add them
|
175
|
+
@attach_handler.add(node, @file_datas2)
|
176
|
+
|
177
|
+
#Check the unchanged file (file2)
|
178
|
+
file2_basename = File.basename(@file2_fname)
|
179
|
+
data2 = @attach_handler.get_raw_data(node, file2_basename)
|
180
|
+
data2.should == @file_stored_data[file2_basename]
|
181
|
+
|
182
|
+
#Get the changed files and verify it is the new data
|
183
|
+
file1_basename = File.basename(@file1_fname)
|
184
|
+
data1 = @attach_handler.get_raw_data(node, file1_basename)
|
185
|
+
data1.should == file1_data
|
186
|
+
|
187
|
+
file3_basename = File.basename(file3_fname)
|
188
|
+
data3 = @attach_handler.get_raw_data(node, file3_basename)
|
189
|
+
data3.should == file3_data
|
190
|
+
|
191
|
+
file4_basename = File.basename(file4_fname)
|
192
|
+
data4 = @attach_handler.get_raw_data(node, file4_basename)
|
193
|
+
data4.should == file4_data
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should delete (subtract) files" do
|
197
|
+
node = @node_mock
|
198
|
+
files_to_delete = [@file1_fname, @file2_fname]
|
199
|
+
#they should exist in the node
|
200
|
+
files_to_delete.each do |fname|
|
201
|
+
file_basename = File.basename(fname)
|
202
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
203
|
+
data.should match /^Example File/
|
204
|
+
end
|
205
|
+
|
206
|
+
basenames_to_delete = files_to_delete.map{|f| File.basename(f)}
|
207
|
+
@attach_handler.subtract(node, basenames_to_delete)
|
208
|
+
|
209
|
+
files_to_delete.each do |fname|
|
210
|
+
file_basename = File.basename(fname)
|
211
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
212
|
+
data.should be_nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should add attachments from the raw data" do
|
217
|
+
node = @node_mock
|
218
|
+
|
219
|
+
raw_data = "Example File3\nYet more text"
|
220
|
+
content_type = "text/plain"
|
221
|
+
modified_at = Time.now.to_s
|
222
|
+
att_name = "example_raw_data.txt"
|
223
|
+
|
224
|
+
#Add the Raw Data
|
225
|
+
@attach_handler.add_raw_data(node, att_name, content_type, raw_data, modified_at)
|
226
|
+
|
227
|
+
#Get the files and verify data
|
228
|
+
|
229
|
+
data = @attach_handler.get_raw_data(node, att_name)
|
230
|
+
md = @attach_handler.get_attachments_metadata(node)[att_name]
|
231
|
+
|
232
|
+
data.should == raw_data
|
233
|
+
md[:content_type].should == content_type
|
234
|
+
md[:file_modified].should == modified_at
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should delete all (subtract_all) files" do
|
238
|
+
node = @node_mock
|
239
|
+
|
240
|
+
#create some more attachments
|
241
|
+
del_data = {}
|
242
|
+
del_data["del_data1"] = "my life will be short"
|
243
|
+
del_data["del_data2"] = "alas too short"
|
244
|
+
|
245
|
+
#add the attachments
|
246
|
+
del_data.each do |name, data|
|
247
|
+
@attach_handler.add_raw_data(node, name, "text/plain", data, Time.now.to_s)
|
248
|
+
end
|
249
|
+
|
250
|
+
#verify it's there
|
251
|
+
del_data.each do |name, data|
|
252
|
+
stored_data = @attach_handler.get_raw_data(node, name)
|
253
|
+
stored_data.should == data
|
254
|
+
end
|
255
|
+
|
256
|
+
#delete it all
|
257
|
+
@attach_handler.subtract(node, :all)
|
258
|
+
|
259
|
+
#verify it's not there
|
260
|
+
del_data.each do |name, data|
|
261
|
+
stored_data = @attach_handler.get_raw_data(node, name)
|
262
|
+
stored_data.should be_nil
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
=begin
|
268
|
+
it "should create object and update the database with a single attachment if there is no other doc in database" do
|
269
|
+
#set initial conditions
|
270
|
+
test_file = @test_files['binary_data_pptx']
|
271
|
+
test_file_basename = File.basename(test_file)
|
272
|
+
test_file_modified_time = File.mtime(test_file)
|
273
|
+
test_doc = @test_doc
|
274
|
+
test_doc_id = @test_doc_id
|
275
|
+
md_params = {}
|
276
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
277
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
278
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
279
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
280
|
+
#test
|
281
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
282
|
+
#check results
|
283
|
+
|
284
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
285
|
+
bia['_id'].should == test_attachment_id
|
286
|
+
#test_doc.attachment_doc_id.should == test_attachment_id
|
287
|
+
#p bia.class
|
288
|
+
#Note the lack of escaping on the file name, this only works
|
289
|
+
#because the original file name did not need escaping
|
290
|
+
bia['md_attachments'][test_file_basename]['file_modified'].should == test_file_modified_time.to_s
|
291
|
+
bia['_attachments'][test_file_basename]['content_type'].should == md_params['content_type']
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
it "should handle file names with strange (but somewhat common) characters and convert to more standard form" do
|
296
|
+
test_file = @test_files['strange_characters_in_file_name']
|
297
|
+
test_file_basename = File.basename(test_file)
|
298
|
+
test_file_modified_time = File.mtime(test_file)
|
299
|
+
test_doc = @test_doc
|
300
|
+
test_doc_id = @test_doc_id
|
301
|
+
#test_doc_id = 'dummy_doc_strange_character_file_name'
|
302
|
+
md_params = {}
|
303
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
304
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
305
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
306
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
307
|
+
#test
|
308
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
309
|
+
#check results
|
310
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
311
|
+
bia['_id'].should == test_attachment_id
|
312
|
+
bia['md_attachments'][TkEscape.escape(test_file_basename)]['file_modified'].should == test_file_modified_time.to_s
|
313
|
+
bia['_attachments'][TkEscape.escape(test_file_basename)]['content_type'].should == md_params['content_type']
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should create multiple attachments in one update" do
|
317
|
+
#set initial conditions
|
318
|
+
test_file1 = @test_files['binary_data2_docx']
|
319
|
+
test_file2 = @test_files['simple_text_file']
|
320
|
+
test_file1_basename = File.basename(test_file1)
|
321
|
+
test_file2_basename = File.basename(test_file2)
|
322
|
+
md_params1 = {}
|
323
|
+
md_params2 = {}
|
324
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
325
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
326
|
+
md_params1['file_modified'] = File.mtime(test_file1).to_s
|
327
|
+
md_params2['file_modified'] = File.mtime(test_file2).to_s
|
328
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
329
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
330
|
+
attachs = { test_file1_basename => {'data' => data1, 'md' => md_params1},
|
331
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
332
|
+
}
|
333
|
+
test_doc = @test_doc
|
334
|
+
test_doc_id = @test_doc_id
|
335
|
+
#test_doc_id = 'dummy_create_multiple_attachments'
|
336
|
+
#test
|
337
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, ::CouchrestAttachment, attachs )
|
338
|
+
#verify results
|
339
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
340
|
+
bia['_id'].should == test_attachment_id
|
341
|
+
bia['md_attachments'][TkEscape.escape(test_file1_basename)]['file_modified'].should == File.mtime(test_file1).to_s
|
342
|
+
bia['_attachments'][TkEscape.escape(test_file1_basename)]['content_type'].should == md_params1['content_type']
|
343
|
+
bia['md_attachments'][TkEscape.escape(test_file2_basename)]['file_modified'].should == File.mtime(test_file2).to_s
|
344
|
+
bia['_attachments'][TkEscape.escape(test_file2_basename)]['content_type'].should == md_params2['content_type']
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should add new files to an existing attachment doc" do
|
348
|
+
#set initial conditions existing attachment
|
349
|
+
test_file1 = @test_files['binary_data2_docx']
|
350
|
+
test_file2 = @test_files['simple_text_file']
|
351
|
+
test_file1_basename = File.basename(test_file1)
|
352
|
+
test_file2_basename = File.basename(test_file2)
|
353
|
+
md_params1 = {}
|
354
|
+
md_params2 = {}
|
355
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
356
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
357
|
+
md_params1['file_modified'] = File.mtime(test_file1).to_s
|
358
|
+
md_params2['file_modified'] = File.mtime(test_file2).to_s
|
359
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
360
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
361
|
+
attachs = { test_file1_basename => {'data' => data1, 'md' => md_params1},
|
362
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
363
|
+
}
|
364
|
+
#test_doc_id = 'dummy_add_new_attachments'
|
365
|
+
test_doc = @test_doc
|
366
|
+
test_doc_id = @test_doc_id
|
367
|
+
bia_existing = CouchrestAttachment.add_attachment_package(test_doc_id, ::CouchrestAttachment, attachs )
|
368
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
369
|
+
#verify attachment exists
|
370
|
+
bia_existing['_id'].should == test_attachment_id
|
371
|
+
#set initial conditions for test file
|
372
|
+
test_file = @test_files['simple_text_file2']
|
373
|
+
test_file_modified_time = File.mtime(test_file)
|
374
|
+
test_file_basename = File.basename(test_file)
|
375
|
+
md_params = {}
|
376
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
377
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
378
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
379
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
380
|
+
bia_existing = CouchrestAttachment.get(bia_existing['_id'])
|
381
|
+
#test
|
382
|
+
bia_updated = bia_existing.class.update_attachment_package(bia_existing, attachs )
|
383
|
+
#verify results
|
384
|
+
#p test_file_basename
|
385
|
+
#p TkEscape.escape(test_file_basename)
|
386
|
+
bia_updated['_id'].should == bia_existing['_id']
|
387
|
+
bia_updated['md_attachments'][TkEscape.escape(test_file_basename)]['file_modified'].should == test_file_modified_time.to_s
|
388
|
+
bia_updated['_attachments'][TkEscape.escape(test_file_basename)]['content_type'].should == md_params['content_type']
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should replace older attachment data with new ones, but not vice versa" do
|
392
|
+
#set initial conditions
|
393
|
+
test_file = @test_files['simple_text_file']
|
394
|
+
test_file_basename = File.basename(test_file)
|
395
|
+
test_file_modified_time = File.mtime(test_file)
|
396
|
+
test_doc = @test_doc
|
397
|
+
test_doc_id = @test_doc_id
|
398
|
+
#test_doc_id = 'dummy_fresh_attachment_replaces_stale'
|
399
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
400
|
+
#create a single record
|
401
|
+
md_params = {}
|
402
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
403
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
404
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
405
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
406
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
407
|
+
#verify initial condition
|
408
|
+
bia['_id'].should == test_attachment_id
|
409
|
+
bia['md_attachments'][TkEscape.escape(test_file_basename)]['file_modified'].should == test_file_modified_time.to_s
|
410
|
+
bia['_attachments'][TkEscape.escape(test_file_basename)]['content_type'].should == md_params['content_type']
|
411
|
+
|
412
|
+
#set initial conditions for fresh and stale file
|
413
|
+
stale_file = @test_files['stale_file']
|
414
|
+
fresh_file = @test_files['fresh_file']
|
415
|
+
stale_basename = File.basename(stale_file)
|
416
|
+
fresh_basename = File.basename(fresh_file)
|
417
|
+
stale_modified_time = File.mtime(stale_file)
|
418
|
+
fresh_modified_time = File.mtime(fresh_file)
|
419
|
+
md_params_stale = {}
|
420
|
+
md_params_fresh = {}
|
421
|
+
md_params_stale['content_type'] = MimeNew.for_ofc_x(stale_file)
|
422
|
+
md_params_fresh['content_type'] = MimeNew.for_ofc_x(fresh_file)
|
423
|
+
md_params_stale['file_modified'] = stale_modified_time.to_s
|
424
|
+
md_params_fresh['file_modified'] = fresh_modified_time.to_s
|
425
|
+
stale_data = File.open(stale_file, 'rb') {|f| f.read}
|
426
|
+
fresh_data = File.open(fresh_file, 'rb') {|f| f.read}
|
427
|
+
attachs = {stale_basename => {'data' => stale_data, 'md' => md_params_stale},
|
428
|
+
fresh_basename => {'data' => fresh_data, 'md' => md_params_fresh}
|
429
|
+
}
|
430
|
+
|
431
|
+
#for creating, use the sid and the method create_.... for updateing, use the sia and the method update...
|
432
|
+
bia_updated = CouchrestAttachment.update_attachment_package(bia, attachs )
|
433
|
+
#verify initial conditions
|
434
|
+
bia_updated['_id'].should == test_attachment_id
|
435
|
+
bia_updated['md_attachments'][TkEscape.escape(stale_basename)]['file_modified'].should == stale_modified_time.to_s
|
436
|
+
bia_updated['_attachments'][TkEscape.escape(stale_basename)]['content_type'].should == md_params_stale['content_type']
|
437
|
+
bia_updated['md_attachments'][TkEscape.escape(fresh_basename)]['file_modified'].should == fresh_modified_time.to_s
|
438
|
+
bia_updated['_attachments'][TkEscape.escape(fresh_basename)]['content_type'].should == md_params_fresh['content_type']
|
439
|
+
#if the above tests pass, then the files and database are synchronized
|
440
|
+
|
441
|
+
sleep 1 #to put some time difference
|
442
|
+
|
443
|
+
unstale_data = stale_data + "\n This data is only for the database"
|
444
|
+
unstale_modified_time = Time.now.to_s
|
445
|
+
#puts "Unstale Mod Time (db is more recent): #{unstale_modified_time}"
|
446
|
+
unstale_content_type = 'text/plain;unstale'
|
447
|
+
unstale_params = {'file_modified' => unstale_modified_time, 'content_type' => unstale_content_type}
|
448
|
+
unstale_attach = { TkEscape.escape(stale_basename) => {'data' => unstale_data, 'md'=> unstale_params } }
|
449
|
+
|
450
|
+
CouchrestAttachment.update_attachment_package(bia, unstale_attach)
|
451
|
+
#database should now have more recent information for @stale_basename
|
452
|
+
|
453
|
+
sleep 1 #to put some time difference
|
454
|
+
#puts "Fresh File Mod Time (file is more recent): #{File.mtime(@fresh_file)}"
|
455
|
+
|
456
|
+
File.open(fresh_file, 'a'){|f| f.write("\n This data is only for the file")}
|
457
|
+
#puts "Fresh File Mod Time (file is more recent): #{File.mtime(@fresh_file)}"
|
458
|
+
#file should now have more recent information for @fresh_basename
|
459
|
+
|
460
|
+
#try and update again with both files
|
461
|
+
md_params_stale2 = {}
|
462
|
+
md_params_fresh2 = {}
|
463
|
+
md_params_stale2['content_type'] = MimeNew.for_ofc_x(stale_file)
|
464
|
+
fresh_content_type = 'text/plain;fresh'
|
465
|
+
md_params_fresh2['content_type'] = fresh_content_type #MimeNew.for_ofc_x(@fresh_file)
|
466
|
+
md_params_stale2['file_modified'] = File.mtime(stale_file).to_s
|
467
|
+
fresh_modified_time = File.mtime(fresh_file).to_s
|
468
|
+
md_params_fresh2['file_modified'] = fresh_modified_time
|
469
|
+
stale_data2 = File.open(stale_file, 'rb') {|f| f.read}
|
470
|
+
fresh_data2 = File.open(fresh_file, 'rb') {|f| f.read}
|
471
|
+
attachs = {TkEscape.escape(stale_basename) => {'data' => stale_data2, 'md' => md_params_stale2},
|
472
|
+
TkEscape.escape(fresh_basename) => {'data' => fresh_data2, 'md' => md_params_fresh2}
|
473
|
+
}
|
474
|
+
#test
|
475
|
+
new_bia = CouchrestAttachment.get(bia['_id'])
|
476
|
+
fresh_bia = CouchrestAttachment.update_attachment_package(new_bia, attachs )
|
477
|
+
|
478
|
+
#verify results
|
479
|
+
#db should have fresh file, but not stale one (and maintain older db attachment)
|
480
|
+
fresh_bia['_id'].should == test_attachment_id
|
481
|
+
fresh_bia['md_attachments'][TkEscape.escape(stale_basename)]['file_modified'].should == unstale_modified_time
|
482
|
+
fresh_bia['_attachments'][TkEscape.escape(stale_basename)]['content_type'].should == unstale_content_type
|
483
|
+
fresh_bia['md_attachments'][TkEscape.escape(fresh_basename)]['file_modified'].should == fresh_modified_time
|
484
|
+
fresh_bia['_attachments'][TkEscape.escape(fresh_basename)]['content_type'].should == fresh_content_type
|
485
|
+
end
|
486
|
+
|
487
|
+
it "should combine all attachment metadata when it is retrieved" do
|
488
|
+
#set initial conditions
|
489
|
+
test_file1 = @test_files['binary_data2_docx']
|
490
|
+
test_file2 = @test_files['simple_text_file']
|
491
|
+
test_file1_basename = File.basename(test_file1)
|
492
|
+
test_file2_basename = File.basename(test_file2)
|
493
|
+
test_file1_modified_time = File.mtime(test_file1)
|
494
|
+
test_file2_modified_time = File.mtime(test_file2)
|
495
|
+
md_params1 = {}
|
496
|
+
md_params2 = {}
|
497
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
498
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
499
|
+
md_params1['file_modified'] = test_file1_modified_time.to_s
|
500
|
+
md_params2['file_modified'] = test_file2_modified_time.to_s
|
501
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
502
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
503
|
+
attachs = {test_file1_basename => {'data' => data1, 'md' => md_params1},
|
504
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
505
|
+
}
|
506
|
+
test_doc = @test_doc
|
507
|
+
test_doc_id = test_doc._model_metadata[:_id]
|
508
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
509
|
+
test_attachment = CouchrestAttachment.get(test_attachment_id)
|
510
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
511
|
+
data = CouchrestAttachment.get_attachments(bia)
|
512
|
+
#puts "SIA data: #{data.inspect}"
|
513
|
+
data[TkEscape.escape(test_file1_basename)]['file_modified'].should == test_file1_modified_time.to_s
|
514
|
+
data[TkEscape.escape(test_file1_basename)]['content_type'].should == MimeNew.for_ofc_x(test_file1)
|
515
|
+
end
|
516
|
+
|
517
|
+
it "should delete attachments" do
|
518
|
+
#set initial conditions
|
519
|
+
test_file1 = @test_files['binary_data2_docx']
|
520
|
+
test_file2 = @test_files['simple_text_file']
|
521
|
+
test_file1_basename = File.basename(test_file1)
|
522
|
+
test_file2_basename = File.basename(test_file2)
|
523
|
+
test_file1_modified_time = File.mtime(test_file1)
|
524
|
+
test_file2_modified_time = File.mtime(test_file2)
|
525
|
+
md_params1 = {}
|
526
|
+
md_params2 = {}
|
527
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
528
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
529
|
+
md_params1['file_modified'] = test_file1_modified_time.to_s
|
530
|
+
md_params2['file_modified'] = test_file2_modified_time.to_s
|
531
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
532
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
533
|
+
attachs = {test_file1_basename => {'data' => data1, 'md' => md_params1},
|
534
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
535
|
+
}
|
536
|
+
test_doc = @test_doc
|
537
|
+
test_doc_id = test_doc._model_metadata[:_id]
|
538
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
539
|
+
test_attachment = CouchrestAttachment.get(test_attachment_id)
|
540
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
541
|
+
#test
|
542
|
+
bia.remove_attachment(test_file1_basename)
|
543
|
+
#verify
|
544
|
+
new_atts = bia.get_attachments
|
545
|
+
#puts "Should be only 1: #{new_atts.keys.inspect}"
|
546
|
+
new_atts.keys.size.should == 1
|
547
|
+
new_atts.keys.first.should == TkEscape.escape(test_file2_basename)
|
548
|
+
|
549
|
+
end
|
550
|
+
end
|
551
|
+
=end
|