tinkit 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/LICENSE +176 -0
  2. data/README +11 -0
  3. data/Rakefile +75 -0
  4. data/lib/glue_envs/couchrest/couchrest_attachment_handler.rb +260 -0
  5. data/lib/glue_envs/couchrest/couchrest_files_mgr.rb +198 -0
  6. data/lib/glue_envs/couchrest_glue_env.rb +536 -0
  7. data/lib/glue_envs/files_mgr_base.rb +51 -0
  8. data/lib/glue_envs/filesystem/filesystem_files_mgr.rb +187 -0
  9. data/lib/glue_envs/filesystem_glue_env.rb +395 -0
  10. data/lib/glue_envs/mysql/mysql_files_mgr.rb +175 -0
  11. data/lib/glue_envs/mysql_glue_env.rb +428 -0
  12. data/lib/glue_envs/sdb_s3/sdb_s3_files_mgr.rb +314 -0
  13. data/lib/glue_envs/sdb_s3_glue_env.rb +248 -0
  14. data/lib/helpers/camel.rb +21 -0
  15. data/lib/helpers/filesystem_helpers.rb +27 -0
  16. data/lib/helpers/hash_helpers.rb +74 -0
  17. data/lib/helpers/log_helper.rb +34 -0
  18. data/lib/helpers/mime_types_new.rb +126 -0
  19. data/lib/helpers/old_more_open_struct.rb +28 -0
  20. data/lib/helpers/require_helper.rb +45 -0
  21. data/lib/helpers/tk_escape.rb +17 -0
  22. data/lib/midas/bufs_data_structure.rb +84 -0
  23. data/lib/midas/node_element_operations.rb +264 -0
  24. data/lib/tinkit.rb +38 -0
  25. data/lib/tinkit_base_node.rb +733 -0
  26. data/lib/tinkit_node_factory.rb +47 -0
  27. data/spec/couchrest_files_mgr_spec.rb +551 -0
  28. data/spec/couchrest_glue_spec.rb +246 -0
  29. data/spec/filesystem_files_mgr_spec.rb +236 -0
  30. data/spec/filesystem_glue_spec.rb +243 -0
  31. data/spec/filesystem_helpers_spec.rb +42 -0
  32. data/spec/helpers/bufs_node_builder.rb +17 -0
  33. data/spec/helpers/bufs_sample_dataset.rb +160 -0
  34. data/spec/helpers/bufs_test_environments.rb +81 -0
  35. data/spec/helpers/tmp_view_cleaner.rb +15 -0
  36. data/spec/lib_helpers/tk_escape_spec.rb +45 -0
  37. data/spec/mysql_files_mgr_spec.rb +250 -0
  38. data/spec/mysql_glue_spec.rb +214 -0
  39. data/spec/node_element_operations_spec.rb +392 -0
  40. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec1.rb +82 -0
  41. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec2.rb +68 -0
  42. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec3.rb +80 -0
  43. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec4.rb +110 -0
  44. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec5.rb +84 -0
  45. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec6.rb +83 -0
  46. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec7.rb +101 -0
  47. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec8.rb +92 -0
  48. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec_all.rb +266 -0
  49. data/spec/sdb_s3_glue_spec.rb +230 -0
  50. data/spec/tinkit_node_factory_spec.rb +1108 -0
  51. metadata +114 -0
@@ -0,0 +1,81 @@
1
+ DirEnvHelpers = File.dirname(__FILE__)
2
+ DirBaseEnvHelpers = File.join(DirEnvHelpers, '../../')
3
+ DirFixEnvHelpers = File.join(DirBaseEnvHelpers, 'bufs_fixtures/bufs_fixtures')
4
+
5
+ #include fixtures
6
+ require DirFixEnvHelpers
7
+
8
+ require 'couchrest'
9
+ node_db_name = "http://bufs.younghawk.org:5984/bufs_test_spec/"
10
+ CouchDB = TinkitFixtures::CouchDB #CouchRest.database!(node_db_name)
11
+ CouchDB.compact!
12
+ CouchDB2 = TinkitFixtures::CouchDB2
13
+ CouchDB2.compact!
14
+ FileSystem1 = "/home/bufs/bufs/sandbox_for_specs/file_system_specs/group1"
15
+ FileSystem2 = "/home/bufs/bufs/sandbox_for_specs/file_system_specs/group2"
16
+
17
+ require File.join(DirBaseEnvHelpers, 'lib/tinkit_node_factory')
18
+
19
+ module UserNodeSpecHelpers
20
+ TinkitNodeLibs = [File.join(DirBaseEnvHelpers,'lib/glue_envs/bufs_couchrest_glue_env')]
21
+ TinkitNodeIncludes = [:CouchRestEnv]
22
+ TinkitFileLibs = [File.join(DirBaseEnvHelpers, 'lib/glue_envs/bufs_filesystem_glue_env')]
23
+ TinkitFileIncludes = [:FileSystemEnv]
24
+ end
25
+
26
+ #TODO: Combine this and the next module
27
+ module NodeHelper
28
+ def self.env_builder(model_name, node_class_id, user_id, path, host = nil)
29
+ #binding data (note this occurs in two different places in the env)
30
+
31
+ key_fields = {:required_keys => [:my_category],
32
+ :primary_key => :my_category }
33
+ #data model
34
+ field_op_set ={:my_category => :static_ops,
35
+ :description => :replace_ops,
36
+ :parent_categories => :list_ops,
37
+ :links => :key_list_ops }
38
+ #op_set_mod => <Using default definitions>
39
+
40
+ data_model = {:field_op_set => field_op_set, :key_fields => key_fields}
41
+
42
+ #persistence layer model
43
+ pmodel_env = { :host => host,
44
+ :path => path,
45
+ :user_id => user_id}
46
+ persist_model = {:name => model_name, :env => pmodel_env, :key_fields => key_fields}
47
+
48
+ #final env model
49
+ env = { :node_class_id => node_class_id,
50
+ :data_model => data_model,
51
+ :persist_model => persist_model }
52
+ end
53
+ end
54
+ #for testing CouchRest model
55
+
56
+ module NodeHelpers
57
+ DefaultNodeParams = {:my_category => 'default',
58
+ :parent_categories => ['default_parent'],
59
+ :description => 'default description'}
60
+
61
+ def get_default_params
62
+ DefaultNodeParams.dup #to avoid a couchrest weirdness don't use the params directly
63
+ end
64
+
65
+ def make_doc_no_attachment(user_class, override_defaults={})
66
+ init_params = get_default_params.merge(override_defaults)
67
+ return user_class.new(init_params)
68
+ end
69
+
70
+ def make_doc_w_attach_from_file(user_class, att_fname, override_defaults={})
71
+ test_filename = att_fname
72
+ test_basename = File.basename(test_filename)
73
+ raise "can't find file #{test_filename.inspect}" unless File.exists?(test_filename)
74
+ new_doc = make_doc_no_attachment(user_class, override_defaults)
75
+ new_doc.__save #doc must be saved before we can attach
76
+ file_data = {:src_filename => test_filename}
77
+ new_doc.files_add(file_data)
78
+ #new_doc.add_data_file(test_filename)
79
+ return new_doc
80
+ end
81
+ end
@@ -0,0 +1,15 @@
1
+ require "fileutils"
2
+
3
+ dirs_to_clean = ["/media-ec2/ec2a/projects/bufs/sandbox_for_specs/bufs_file_view_maker_spec/SampleCouchUser001",
4
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/bufs_file_view_maker_spec/SampleCouchUser002",
5
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/sample_data/SampleFileSysUser003/aa",
6
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/sample_data/SampleFileSysUser003/b",
7
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/sample_data/SampleFileSysUser003/c",
8
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/sample_data/SampleFileSysUser004/aa",
9
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/sample_data/SampleFileSysUser004/b",
10
+ "/media-ec2/ec2a/projects/bufs/sandbox_for_specs/sample_data/SampleFileSysUser004/c"]
11
+
12
+ dirs_to_clean.each do |dir|
13
+ FileUtils.rm_rf(dir)
14
+ end
15
+
@@ -0,0 +1,45 @@
1
+ #require helper for cleaner require statements
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../../lib/tinkit')
3
+
4
+ require 'couchrest'
5
+
6
+ require Tinkit.fixtures 'bufs_fixtures'
7
+ require Tinkit.helpers 'tk_escape'
8
+
9
+ doc_db_name = "http://127.0.0.1:5984/tk_escape_spec/"
10
+ EscapeTestDB = CouchRest.database!(doc_db_name)
11
+ EscapeTestDB.compact!
12
+
13
+ describe TkEscape do
14
+
15
+ before(:each) do
16
+ EscapeTestDB.recreate!
17
+ end
18
+
19
+ it "should escape and unescape properly to the database" do
20
+ #set initial conditions
21
+ test_file_name = TinkitFixtures.test_files['strange_characters_in_file_name']
22
+ test_file_basename = File.basename(test_file_name)
23
+ test_file_data = File.open(test_file_name) {|f| f.read}
24
+ test_doc_params = {'_id' => 'test_doc'}
25
+ EscapeTestDB.save_doc(test_doc_params)
26
+ doc = EscapeTestDB.get(test_doc_params['_id'])
27
+ #test
28
+ att_name = TkEscape.escape(test_file_basename)
29
+ EscapeTestDB.put_attachment(doc, att_name, test_file_data)
30
+ #verify results
31
+ couchdb_name = EscapeTestDB.get(test_doc_params['_id'])['_attachments'].keys.first
32
+ att_name.should == couchdb_name
33
+
34
+ #test round trip
35
+ EscapeTestDB.delete_attachment(EscapeTestDB.get(test_doc_params['_id']), att_name)
36
+ EscapeTestDB.put_attachment(EscapeTestDB.get(test_doc_params['_id']), couchdb_name, test_file_data)
37
+ couchdb_name_rt1 = EscapeTestDB.get(test_doc_params['_id'])['_attachments'].keys.first
38
+
39
+ #verify results
40
+ att_name.should == couchdb_name_rt1
41
+
42
+ EscapeTestDB.delete_doc(EscapeTestDB.get(test_doc_params['_id']))
43
+ end
44
+ end
45
+
@@ -0,0 +1,250 @@
1
+ #require helper for cleaner require statements
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/helpers/require_helper')
3
+ require Tinkit.glue 'mysql/mysql_files_mgr'
4
+
5
+ include MysqlInterface
6
+ GlueEnvMock = Struct.new(:model_key, :file_mgr_table)
7
+
8
+ describe FilesMgr, "Setup and intialization" do
9
+
10
+ before(:all) do
11
+
12
+ @glue_env_mock = GlueEnvMock.new("_id", "fake_file_table_name")
13
+ @node_key = :_id
14
+
15
+ file1_data = "Example File1\nJust some text"
16
+ file2_data = "Example File2\nJust some more text"
17
+ file1_fname = "/tmp/example_file1.txt"
18
+ file2_fname = "/tmp/example_file2.txt"
19
+ files = {file1_fname => file1_data, file2_fname => file2_data}
20
+ files.each do |fname, data|
21
+ File.open(fname, 'w'){|f| f.write(data)}
22
+ end
23
+ @file_datas = [{:src_filename => @file1_fname}, {:src_filename => file2_fname}]
24
+ @node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
25
+ end
26
+
27
+ it "should initialize" do
28
+
29
+ #we're not creating the table yet, as that depends on the glue and user
30
+ node_key_value = @node1_data[@node_key]
31
+ attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
32
+
33
+ #note actual table is setup in glue_env, not file_mgr
34
+ attach_handler.file_table_name.should == @glue_env_mock.file_mgr_table
35
+ end
36
+ end
37
+
38
+ describe FilesMgr, "Basic Operations" do
39
+ before(:all) do
40
+ @file_table_name = "attachment_spec__node_loc"
41
+ @file1_fname = "/tmp/example_file1.txt"
42
+ @file2_fname = "/tmp/example_file2.txt"
43
+ f1_bname = File.basename(@file1_fname)
44
+ f2_bname = File.basename(@file2_fname)
45
+ @file_stored_data = { f1_bname => File.open(@file1_fname, 'rb'){|f| f.read},
46
+ f2_bname =>File.open(@file2_fname, 'rb'){|f| f.read} }
47
+
48
+ @mock_key = :_id
49
+ @nodeMockClass = Struct.new(@mock_key, :my_GlueEnv)
50
+
51
+ @glue_env_mock = GlueEnvMock.new(@mock_key.to_s,
52
+ @file_table_name)
53
+
54
+ #set up table for spec
55
+
56
+ primary_key = '__pkid-file'
57
+ home_dir = ENV["HOME"]
58
+ my_pw = File.open("#{home_dir}/.locker/tinkit_mysql"){|f| f.read}.strip
59
+ @dbh = DBI.connect("DBI:Mysql:tinkit:localhost", "tinkit", my_pw)
60
+
61
+ sql = "CREATE TABLE IF NOT EXISTS `#{@file_table_name}` (
62
+ `#{primary_key}` INT NOT NULL AUTO_INCREMENT,
63
+ node_name VARCHAR(255),
64
+ basename VARCHAR(255) NOT NULL,
65
+ content_type VARCHAR(255),
66
+ modified_at VARCHAR(255),
67
+ raw_content LONGBLOB,
68
+ PRIMARY KEY (`#{primary_key}`),
69
+ UNIQUE KEY (node_name, basename) )"
70
+ @dbh.do(sql)
71
+ #
72
+ @file_datas = [{:src_filename => @file1_fname}, {:src_filename => @file2_fname}]
73
+ end
74
+
75
+
76
+ before(:each) do
77
+ @node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
78
+ @node_mock = @nodeMockClass.new(@node1_data[@mock_key],
79
+ @glue_env_mock)
80
+
81
+ node_key_value = @node1_data[@node_key]
82
+ @attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
83
+ #@attach_handler.subtract_files(nil, :all)
84
+ end
85
+
86
+ after(:all) do
87
+ sql = "DROP TABLE `#{@file_table_name}`"
88
+ @dbh.do(sql)
89
+ end
90
+
91
+ it "should add and retrieve files" do
92
+ node = @node_mock
93
+
94
+ @file_datas.each do |file_data|
95
+ file_basename = File.basename(file_data[:src_filename])
96
+ data = @attach_handler.get_raw_data(node, file_basename)
97
+ data.should be_nil
98
+ end
99
+
100
+ #Add the Files
101
+ @attach_handler.add(node, @file_datas)
102
+
103
+ #Get the files and verify data
104
+ @file_datas.each do |file_data|
105
+ file_basename = File.basename(file_data[:src_filename])
106
+ data = @attach_handler.get_raw_data(node, file_basename)
107
+ data.should == @file_stored_data[file_basename]
108
+ end
109
+ end
110
+
111
+ it "should list attachment files" do
112
+ files = @attach_handler.list(@node_mock)
113
+ files.sort.should == @file_stored_data.keys.sort
114
+ end
115
+
116
+ it "should list metadata" do
117
+
118
+ md = @attach_handler.get_attachments_metadata(@node_mock)
119
+ md.should_not == nil
120
+ @file_datas.each do |file_data|
121
+ file_basename = File.basename(file_data[:src_filename])
122
+ each_md = md[file_basename]
123
+ each_md.should_not == nil
124
+ each_md.keys.should include :content_type
125
+ each_md.keys.should include :file_modified
126
+
127
+ file_basename = File.basename(file_data[:src_filename])
128
+ md[file_basename][:content_type].should =~ /^text\/plain/
129
+ time_str = md[file_basename][:file_modified]
130
+ Time.parse(time_str).should > Time.now - 1 #should have been modified less than a second ago
131
+ end
132
+ end
133
+
134
+ it "should be well behaved adding more files" do
135
+ node = @node_mock
136
+
137
+ #Get the original files and verify data
138
+ @file_datas.each do |file_data|
139
+ file_basename = File.basename(file_data[:src_filename])
140
+ data = @attach_handler.get_raw_data(node, file_basename)
141
+ data.should == @file_stored_data[file_basename]
142
+ end
143
+
144
+ #create some more files
145
+ file1_data = "Example File1\nNEW!! text"
146
+ file3_data = "Example File3\nYet more text"
147
+ file4_data = "Example File4\nand more text"
148
+ file3_fname = "/tmp/example_file3.txt"
149
+ file4_fname = "/tmp/example_file4.txt"
150
+ files = {@file1_fname => file1_data, file3_fname => file3_data, file4_fname => file4_data}
151
+ files.each do |fname, data|
152
+ File.open(fname, 'w'){|f| f.write(data)}
153
+ end
154
+ file1_data.should == File.open(@file1_fname){|f| f.read}
155
+ @file_datas2 = [{:src_filename => @file1_fname},
156
+ {:src_filename => file3_fname},
157
+ {:src_filename => file4_fname}]
158
+
159
+ #add them
160
+ @attach_handler.add(node, @file_datas2)
161
+
162
+ #Check the unchanged file (file2)
163
+ file2_basename = File.basename(@file2_fname)
164
+ data2 = @attach_handler.get_raw_data(node, file2_basename)
165
+ data2.should == @file_stored_data[file2_basename]
166
+
167
+ #Get the changed files and verify it is the new data
168
+ file1_basename = File.basename(@file1_fname)
169
+ data1 = @attach_handler.get_raw_data(node, file1_basename)
170
+ data1.should == file1_data
171
+
172
+ file3_basename = File.basename(file3_fname)
173
+ data3 = @attach_handler.get_raw_data(node, file3_basename)
174
+ data3.should == file3_data
175
+
176
+ file4_basename = File.basename(file4_fname)
177
+ data4 = @attach_handler.get_raw_data(node, file4_basename)
178
+ data4.should == file4_data
179
+ end
180
+
181
+ it "should delete (subtract) files" do
182
+ node = @node_mock
183
+ files_to_delete = [@file1_fname, @file2_fname]
184
+ #they should exist in the node
185
+ files_to_delete.each do |fname|
186
+ file_basename = File.basename(fname)
187
+ data = @attach_handler.get_raw_data(node, file_basename)
188
+ data.should match /^Example File/
189
+ end
190
+
191
+ basenames_to_delete = files_to_delete.map{|f| File.basename(f)}
192
+ @attach_handler.subtract(node, basenames_to_delete)
193
+
194
+ files_to_delete.each do |fname|
195
+ file_basename = File.basename(fname)
196
+ data = @attach_handler.get_raw_data(node, file_basename)
197
+ data.should be_nil
198
+ end
199
+ end
200
+
201
+ it "should add attachments from the raw data" do
202
+ node = @node_mock
203
+
204
+ raw_data = "Example File3\nYet more text"
205
+ content_type = "text/plain"
206
+ modified_at = Time.now.to_s
207
+ att_name = "example_raw_data.txt"
208
+
209
+ #Add the Raw Data
210
+ @attach_handler.add_raw_data(node, att_name, content_type, raw_data, modified_at)
211
+
212
+ #Get the files and verify data
213
+
214
+ data = @attach_handler.get_raw_data(node, att_name)
215
+ md = @attach_handler.get_attachments_metadata(node)[att_name]
216
+
217
+ data.should == raw_data
218
+ md[:content_type].should == content_type
219
+ md[:file_modified].should == modified_at
220
+ end
221
+
222
+ it "should delete all (subtract_all) files" do
223
+ node = @node_mock
224
+
225
+ #create some more attachments
226
+ del_data = {}
227
+ del_data["del_data1"] = "my life will be short"
228
+ del_data["del_data2"] = "alas too short"
229
+
230
+ #add the attachments
231
+ del_data.each do |name, data|
232
+ @attach_handler.add_raw_data(node, name, "text/plain", data, Time.now.to_s)
233
+ end
234
+
235
+ #verify it's there
236
+ del_data.each do |name, data|
237
+ stored_data = @attach_handler.get_raw_data(node, name)
238
+ stored_data.should == data
239
+ end
240
+
241
+ #delete it all
242
+ @attach_handler.subtract(node, :all)
243
+
244
+ #verify it's not there
245
+ del_data.each do |name, data|
246
+ stored_data = @attach_handler.get_raw_data(node, name)
247
+ stored_data.should be_nil
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,214 @@
1
+ #require helper for cleaner require statements
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/helpers/require_helper')
3
+
4
+ require Tinkit.glue 'mysql_glue_env'
5
+
6
+
7
+
8
+ describe MysqlEnv::GlueEnv, "Initialization" do
9
+
10
+ before(:each) do
11
+ #host is the database
12
+ persist_env = {:host => nil, :path => 'test_domain', :user_id => 'init_test_user'}
13
+ @persist_env = {:name => 'mysql_glue_test', :env => persist_env}
14
+ key_fields = {:required_keys => [:my_id],
15
+ :primary_key => :my_id }
16
+ @data_model_bindings = {:key_fields => key_fields, :views => nil}
17
+ end
18
+
19
+ it "should initialize properly" do
20
+ mysql_glue_obj = MysqlEnv::GlueEnv.new(@persist_env, @data_model_bindings)
21
+ mysql_glue_obj.dbh.connected?.should == true
22
+
23
+ mysql_glue_obj.user_id.should == @persist_env[:env][:user_id]
24
+ mysql_glue_obj.required_instance_keys.should == @data_model_bindings[:key_fields][:required_keys]
25
+ mysql_glue_obj.required_save_keys.should == @data_model_bindings[:key_fields][:required_keys]
26
+ mysql_glue_obj.node_key.should == @data_model_bindings[:key_fields][:primary_key]
27
+ mysql_glue_obj.metadata_keys.should == [mysql_glue_obj.persist_layer_key,
28
+ mysql_glue_obj.version_key,
29
+ mysql_glue_obj.namespace_key]
30
+ path = @persist_env[:env][:path]
31
+ mysql_glue_obj.user_datastore_location.should == "#{path}__#{mysql_glue_obj.user_id}"
32
+ mysql_glue_obj._files_mgr_class.class.should_not == nil #temp test
33
+ #sdb_glue_obj.views.should_not == nil #temp test
34
+ #sdb_glue_obj.moab_data.should_not == nil #temp test
35
+ end
36
+ end
37
+
38
+ describe MysqlEnv::GlueEnv, "Persistent Layer Basic Operations" do
39
+
40
+ before(:each) do
41
+ env = {:host => nil, :path => 'test_domain', :user_id => 'init_test_user'}
42
+ @persist_env = {:env => env}
43
+ key_fields = {:required_keys => [:my_id],
44
+ :primary_key => :my_id }
45
+ @data_model_bindings = {:key_fields => key_fields, :views => nil}
46
+ @mysql_glue_obj = MysqlEnv::GlueEnv.new(@persist_env, @data_model_bindings)
47
+ end
48
+
49
+ after(:each) do
50
+ table = @mysql_glue_obj.model_save_params[:table]
51
+ dbh = @mysql_glue_obj.model_save_params[:dbh]
52
+ sql = "DROP TABLE `#{table}`"
53
+ dbh.do(sql)
54
+ end
55
+
56
+ it "should persist data and be able to retrieve it" do
57
+ @mysql_glue_obj.should_not == nil
58
+ #:id was defined as the primary key
59
+ data1 = {:my_id => "test_id1", :data => "test data"}
60
+ empty_data = @mysql_glue_obj.get(data1[:my_id]) #hasn't been saved yet
61
+ empty_data.should == nil
62
+ @mysql_glue_obj.save(data1)
63
+ #Don't use native get_attributes, use obj's get, it will block until save is finished
64
+ persisted_data = @mysql_glue_obj.get(data1[:my_id])
65
+ persisted_data.should_not == nil
66
+ #p persisted_data
67
+ persisted_data[:my_id].should == data1[:my_id]
68
+ persisted_data[:data].should == data1[:data]
69
+ end
70
+
71
+ it "should be able to delete data" do
72
+ data1 = {:my_id => "test_id1", :data => "test data1"}
73
+ data2 = {:my_id => "test_id2", :data => "test data2"}
74
+ @mysql_glue_obj.save(data1)
75
+ @mysql_glue_obj.save(data2)
76
+ persisted_data1 = @mysql_glue_obj.get(data1[:my_id])
77
+ persisted_data2 = @mysql_glue_obj.get(data2[:my_id])
78
+ persisted_data1[:data].should == "test data1"
79
+ persisted_data2[:data].should == "test data2"
80
+ @mysql_glue_obj.destroy_node({:my_id => data2[:my_id]})
81
+ persisted_data1 = @mysql_glue_obj.get(data1[:my_id])
82
+ persisted_data2 = @mysql_glue_obj.get(data2[:my_id])
83
+ persisted_data1[:data].should == "test data1"
84
+ persisted_data2.should == nil
85
+ end
86
+ end
87
+
88
+ describe MysqlEnv::GlueEnv, "Persistent Layer Collection Operations" do
89
+
90
+ before(:each) do
91
+ env = {:host => nil, :path => 'test_domain', :user_id => 'init_test_user'}
92
+ @persist_env = {:env => env}
93
+ key_fields = {:required_keys => [:my_id],
94
+ :primary_key => :my_id }
95
+ @data_model_bindings = {:key_fields => key_fields, :views => nil}
96
+ @mysql_glue_obj = MysqlEnv::GlueEnv.new(@persist_env, @data_model_bindings)
97
+ end
98
+
99
+ after(:each) do
100
+ table = @mysql_glue_obj.model_save_params[:table]
101
+ dbh = @mysql_glue_obj.model_save_params[:dbh]
102
+ sql = "DROP TABLE `#{table}`"
103
+ dbh.do(sql)
104
+ end
105
+
106
+ it "should be able to query all" do
107
+ data1 = {:my_id => "test_id1", :data => "test data1"}
108
+ data2 = {:my_id => "test_id2", :data => "test data2"}
109
+ @mysql_glue_obj.save(data1)
110
+ @mysql_glue_obj.save(data2)
111
+
112
+ results = @mysql_glue_obj.query_all
113
+ #results.should == 'blah'
114
+ results.each do |raw_data|
115
+ case raw_data[:my_id]
116
+ when "test_id1"
117
+ raw_data[:data].should == "test data1"
118
+ when "test_id2"
119
+ raw_data[:data].should == "test data2"
120
+ else
121
+ raise "Unknown dataset"
122
+ end#case
123
+ end#each
124
+ end
125
+
126
+ it "should be able to find matching data" do
127
+ data1 = {:my_id => "test_id1", :data => "test data1", :tags => ['a', 'b', 'c']}
128
+ data2 = {:my_id => "test_id2", :data => "test data2", :tags => ['c', 'd', 'e']}
129
+ data3 = {:my_id => "test_id3", :data => "test data2", :tags => ['c', 'b', 'z']}
130
+ data_list = [data1, data2, data3]
131
+ data_list.each {|data| @mysql_glue_obj.save(data)}
132
+
133
+ result1 = @mysql_glue_obj.find_nodes_where(:my_id, :equals, "test_id1")
134
+ result1.size.should == 1
135
+ result1.first[:my_id].should == "test_id1"
136
+
137
+ result2 = @mysql_glue_obj.find_nodes_where(:my_id, :equals, "oops")
138
+ result2.should be_empty
139
+
140
+ result3 = @mysql_glue_obj.find_nodes_where(:data, :equals, "test data2")
141
+ result3.size.should == 2
142
+ ["test_id2", "test_id3"].should include result3.first[:my_id]
143
+ ["test_id2", "test_id3"].should include result3.last[:my_id]
144
+
145
+ result4 = @mysql_glue_obj.find_nodes_where(:tags, :equals, ['c', 'd', 'e'])
146
+ result4.size.should == 1
147
+ result4.first[:my_id].should == "test_id2"
148
+ end
149
+
150
+ it "should be able to find containting data" do
151
+ data1 = {:my_id => "test_id1", :data => "test data1", :tags => ['a', 'b', 'c']}
152
+ data2 = {:my_id => "test_id2", :data => "test data2", :tags => ['c', 'd', 'e']}
153
+ data3 = {:my_id => "test_id3", :data => "test data2", :tags => ['c', 'b', 'z']}
154
+ data_list = [data1, data2, data3]
155
+ data_list.each {|data| @mysql_glue_obj.save(data)}
156
+
157
+ result1 = @mysql_glue_obj.find_nodes_where(:my_id, :contains, "test_id2")
158
+ result1.size.should == 1
159
+ result1.first[:my_id].should == "test_id2"
160
+
161
+ result2 = @mysql_glue_obj.find_nodes_where(:tags, :contains, "c")
162
+ result2.size.should == 3
163
+
164
+ result3 = @mysql_glue_obj.find_nodes_where(:tags, :contains, "b")
165
+ result3.size.should == 2
166
+ ["test_id1", "test_id3"].should include result3.first[:my_id]
167
+ ["test_id1", "test_id3"].should include result3.last[:my_id]
168
+
169
+ result4 = @mysql_glue_obj.find_nodes_where(:tags, :contains, "oops")
170
+ result4.should be_empty
171
+ end
172
+
173
+ it "should be able to delete in bulk" do
174
+ data1 = {:my_id => "test_id1", :data => "delete me"}
175
+ data2 = {:my_id => "test_id2", :data => "keep me"}
176
+ data3 = {:my_id => "test_id3", :data => "delete me too"}
177
+ @mysql_glue_obj.save(data1)
178
+ @mysql_glue_obj.save(data2)
179
+ @mysql_glue_obj.save(data3)
180
+
181
+ results = @mysql_glue_obj.query_all
182
+ results.each do |raw_data|
183
+ case raw_data[:my_id]
184
+ when "test_id1"
185
+ raw_data[:data].should == "delete me"
186
+ when "test_id2"
187
+ raw_data[:data].should == "keep me"
188
+ when "test_id3"
189
+ raw_data[:data].should == "delete me too"
190
+ else
191
+ raise "Unknown dataset"
192
+ end#case
193
+ end#each
194
+
195
+ raw_rcds_to_delete = [data1, data3]
196
+ @mysql_glue_obj.destroy_bulk(raw_rcds_to_delete)
197
+
198
+ results = @mysql_glue_obj.query_all
199
+ #puts "Destroy Bulk results: #{results.inspect}"
200
+ results.each do |raw_data|
201
+ case raw_data[:my_id]
202
+ when "test_id1"
203
+ raise "Oops should have been deleted"
204
+ when "test_id2"
205
+ raw_data[:data].should == "keep me"
206
+ when "test_id3"
207
+ raise "Oops should have been deleted"
208
+ else
209
+ raise "Unknown dataset"
210
+ end#case
211
+ end#each
212
+ end#it
213
+ end
214
+