rbbt-util 5.5.68 → 5.6.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rbbt/association.rb +1 -1
  3. data/lib/rbbt/association/index.rb +2 -1
  4. data/lib/rbbt/entity.rb +2 -0
  5. data/lib/rbbt/persist/tsv.rb +46 -232
  6. data/lib/rbbt/persist/tsv/cdb.rb +139 -0
  7. data/lib/rbbt/persist/tsv/kyotocabinet.rb +168 -0
  8. data/lib/rbbt/persist/tsv/leveldb.rb +121 -0
  9. data/lib/rbbt/persist/tsv/lmdb.rb +148 -0
  10. data/lib/rbbt/persist/tsv/tokyocabinet.rb +158 -0
  11. data/lib/rbbt/resource/rake.rb +2 -1
  12. data/lib/rbbt/tsv/accessor.rb +74 -101
  13. data/lib/rbbt/tsv/parser.rb +2 -5
  14. data/lib/rbbt/tsv/serializers.rb +6 -0
  15. data/lib/rbbt/tsv/util.rb +8 -2
  16. data/lib/rbbt/util/R.rb +6 -0
  17. data/lib/rbbt/util/cmd.rb +7 -4
  18. data/lib/rbbt/util/misc.rb +10 -4
  19. data/lib/rbbt/util/open.rb +8 -6
  20. data/lib/rbbt/util/simpleopt.rb +1 -1
  21. data/lib/rbbt/workflow.rb +17 -3
  22. data/lib/rbbt/workflow/accessor.rb +5 -1
  23. data/lib/rbbt/workflow/definition.rb +6 -0
  24. data/lib/rbbt/workflow/step.rb +10 -4
  25. data/lib/rbbt/workflow/task.rb +1 -1
  26. data/share/rbbt_commands/tsv/json +37 -0
  27. data/share/rbbt_commands/workflow/task +8 -2
  28. data/test/rbbt/persist/test_tsv.rb +77 -0
  29. data/test/rbbt/persist/tsv/test_cdb.rb +23 -0
  30. data/test/rbbt/persist/tsv/test_kyotocabinet.rb +33 -0
  31. data/test/rbbt/persist/tsv/test_leveldb.rb +22 -0
  32. data/test/rbbt/persist/tsv/test_lmdb.rb +22 -0
  33. data/test/rbbt/persist/tsv/test_tokyocabinet.rb +242 -0
  34. data/test/rbbt/test_persist.rb +1 -225
  35. data/test/rbbt/test_workflow.rb +0 -1
  36. data/test/rbbt/workflow/test_step.rb +14 -12
  37. data/test/test_helper.rb +4 -2
  38. metadata +20 -4
  39. data/test/rbbt/workflow/test_soap.rb +0 -105
@@ -95,7 +95,7 @@ module SOPT
95
95
  def self.parse(opts)
96
96
  info = {}
97
97
 
98
- opts.split(/:/).each do |opt|
98
+ opts.split(/[:\n]+/).each do |opt|
99
99
  next if opt.strip.empty?
100
100
 
101
101
  short, long = opt.strip.sub(/(^[^\s]*)\*/,'\1').split('--').values_at(0,1)
data/lib/rbbt/workflow.rb CHANGED
@@ -196,9 +196,13 @@ module Workflow
196
196
 
197
197
  dependencies = real_dependencies(task, jobname, inputs, task_dependencies[taskname] || [])
198
198
 
199
- input_values = task.take_input_values(inputs)
200
-
201
- step_path = step_path taskname, jobname, input_values, dependencies
199
+ if inputs.empty?
200
+ step_path = step_path taskname, jobname, [], [], task.extension
201
+ input_values = task.take_input_values(inputs)
202
+ else
203
+ input_values = task.take_input_values(inputs)
204
+ step_path = step_path taskname, jobname, input_values, dependencies, task.extension
205
+ end
202
206
 
203
207
  step = Step.new step_path, task, input_values, dependencies
204
208
 
@@ -258,4 +262,14 @@ module Workflow
258
262
  local_persist_setup
259
263
  local_workdir_setup
260
264
  end
265
+
266
+ def with_workdir(workdir)
267
+ saved = self.workdir
268
+ begin
269
+ self.workdir = Path.setup(File.expand_path(workdir))
270
+ yield
271
+ ensure
272
+ self.workdir = saved
273
+ end
274
+ end
261
275
  end
@@ -281,7 +281,7 @@ module Workflow
281
281
  end
282
282
 
283
283
  TAG = :hash
284
- def step_path(taskname, jobname, inputs, dependencies)
284
+ def step_path(taskname, jobname, inputs, dependencies, extension = nil)
285
285
  Proc.new{
286
286
  raise "Jobname makes an invalid path: #{ jobname }" if jobname =~ /\.\./
287
287
  if inputs.any? or dependencies.any?
@@ -295,6 +295,10 @@ module Workflow
295
295
  tagged_jobname = jobname
296
296
  end
297
297
 
298
+ if extension and not extension.empty?
299
+ tagged_jobname = tagged_jobname + ('.' << extension.to_s)
300
+ end
301
+
298
302
  workdir[taskname][tagged_jobname].find
299
303
  }
300
304
  end
@@ -7,6 +7,7 @@ module Workflow
7
7
  AnnotatedModule.add_consummable_annotation(self,
8
8
  :result_description => "",
9
9
  :result_type => nil,
10
+ :extension => '',
10
11
  :dependencies => [])
11
12
  def helper(name, &block)
12
13
  helpers[name] = block
@@ -16,6 +17,10 @@ module Workflow
16
17
  @description = description
17
18
  end
18
19
 
20
+ def extension(extension)
21
+ @extension = extension
22
+ end
23
+
19
24
  def returns(description)
20
25
  @result_description = description
21
26
  end
@@ -45,6 +50,7 @@ module Workflow
45
50
  :result_type => (Array === type ? type.to_sym : type),
46
51
  :input_defaults => consume_input_defaults,
47
52
  :input_descriptions => consume_input_descriptions,
53
+ :extension => consume_extension,
48
54
  :input_options => consume_input_options
49
55
  }
50
56
 
@@ -92,12 +92,18 @@ class Step
92
92
  self
93
93
  end
94
94
 
95
+ def checks
96
+ deps = rec_dependencies.collect{|dependency| dependency.path }.uniq
97
+ deps.select!{|p| p.exists? }
98
+ end
99
+
95
100
  def run(no_load = false)
96
- result = Persist.persist "Job", @task.result_type, :file => path, :check => rec_dependencies.collect{|dependency| dependency.path }.uniq, :no_load => no_load do
97
- @exec = false
101
+
102
+ result = Persist.persist "Job", @task.result_type, :file => path, :check => checks, :no_load => no_load do
98
103
  if Step === Step.log_relay_step and not self == Step.log_relay_step
99
104
  relay_log(Step.log_relay_step) unless self.respond_to? :relay_step and self.relay_step
100
105
  end
106
+ @exec = false
101
107
 
102
108
  Open.rm info_file if Open.exists? info_file
103
109
 
@@ -149,7 +155,7 @@ class Step
149
155
  backtrace = $!.backtrace
150
156
 
151
157
  # HACK: This fixes an strange behaviour in 1.9.3 where some
152
- # bactrace strings are coded in ASCII-8BIT
158
+ # backtrace strings are coded in ASCII-8BIT
153
159
  backtrace.each{|l| l.force_encoding("UTF-8")} if String.instance_methods.include? :force_encoding
154
160
 
155
161
  set_info :backtrace, backtrace
@@ -251,7 +257,7 @@ class Step
251
257
 
252
258
  def load
253
259
  raise "Can not load: Step is waiting for proces #{@pid} to finish" if not done?
254
- result = Persist.persist "Job", @task.result_type, :file => @path, :check => rec_dependencies.collect{|dependency| dependency.path} do
260
+ result = Persist.persist "Job", @task.result_type, :file => @path, :check => checks do
255
261
  exec
256
262
  end
257
263
  prepare_result result, @task.result_description, info
@@ -2,7 +2,7 @@ require 'rbbt/util/misc'
2
2
  require 'rbbt/persist'
3
3
 
4
4
  module Task
5
- attr_accessor :inputs, :input_types, :result_type, :input_defaults, :input_descriptions, :input_options, :description, :name, :result_description
5
+ attr_accessor :inputs, :input_types, :result_type, :input_defaults, :input_descriptions, :input_options, :description, :name, :result_description, :extension
6
6
 
7
7
  def self.setup(options = {}, &block)
8
8
  block.extend Task
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rbbt-util'
4
+ require 'rbbt/util/simpleopt'
5
+
6
+ options = SOPT.get("-tch--tokyocabinet:-tcb--tokyocabinet_bd:-m--melt:-s--snake_case")
7
+
8
+ file = ARGV.shift
9
+
10
+ case
11
+ when options[:tokyocabinet]
12
+ tsv = Persist.open_tokyocabinet(file, false)
13
+ when options[:tokyocabinet_bd]
14
+ tsv = Persist.open_tokyocabinet(file, false, nil, TokyoCabinet::BDB)
15
+ else
16
+ tsv = TSV.open(Open.open(file))
17
+ end
18
+
19
+ fields = tsv.fields
20
+
21
+ if options[:snake_case]
22
+ tsv.fields = fields = fields.collect{|f| Misc.snake_case f}
23
+ end
24
+
25
+ raise "No fields specified" if fields.nil?
26
+ if options[:melt]
27
+ puts tsv.to_hash.collect{|key, values|
28
+ h = {:key => key}
29
+ fields.zip(values).each do |field, v|
30
+ h[field] = v
31
+ end
32
+ h
33
+ }.to_json
34
+ else
35
+ puts tsv.to_hash.to_json
36
+ end
37
+
@@ -112,6 +112,8 @@ options = SOPT.get <<EOF
112
112
  -rcl--recursive_clean Clean the last step and its dependencies to recompute the job completely:
113
113
  -jn--jobname* Job name to use. The name 'Default' is used by default:
114
114
  -pn--printname Print the name of the job and exit without starting it:
115
+ -wd--workdir* Change the working directory of the workflow:
116
+ -O--output* Save job result into file:
115
117
  --fork Run job asyncronously:
116
118
  EOF
117
119
 
@@ -169,6 +171,8 @@ sopt_option_string = SOPT_options(workflow, task)
169
171
  job_options = SOPT.get sopt_option_string
170
172
  job_options = fix_options(workflow, task, job_options)
171
173
 
174
+ workflow.workdir = Path.setup(File.expand_path(options.delete(:workdir))) if options[:workdir]
175
+
172
176
  #- get job
173
177
 
174
178
  job = workflow.job(task.name, name, job_options)
@@ -226,10 +230,12 @@ rescue ParameterException
226
230
  usage(workflow, task, $!.message)
227
231
  end
228
232
 
233
+ out = options.include?(:output) ? File.open(options[:output], 'wb') : STDOUT
234
+
229
235
  if Step === res
230
- puts Open.read(res.path) if File.exists? res.path
236
+ out.puts Open.read(res.path) if File.exists? res.path
231
237
  else
232
- puts res
238
+ out.puts res
233
239
  end
234
240
 
235
241
  exit 0
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+ require 'rbbt/persist'
3
+ require 'rbbt/annotations'
4
+ require 'rbbt/util/tmpfile'
5
+ require 'test/unit'
6
+
7
+
8
+
9
+ class TestPersistTSV < Test::Unit::TestCase
10
+ MAX = 100_002
11
+
12
+ def tsv_path
13
+ Random.new
14
+ #require 'rbbt/sources/organism'
15
+ #Organism.identifiers("Hsa")
16
+ require 'rbbt/workflow'
17
+ Workflow.require_workflow "Genomics"
18
+ require 'rbbt/entity/gene'
19
+ require 'rbbt/sources/genomes1000'
20
+ CMD.cmd("grep -v '^\\.\t' | head -n #{MAX}", :in => Genomes1000.mutations.open, :pipe => true)
21
+ end
22
+
23
+ def run_bechmark(file, engine)
24
+ Log.info "Testing #{ Term::ANSIColor.red(engine) }"
25
+ TmpFile.with_file nil, false do |tmp_file|
26
+ db= nil
27
+ Misc.benchmark(1, "Build database with #{MAX - 2} entries") do
28
+ db = TSV.open(file, :fields => [1], :persist => true, :persist_engine => engine, :persist_dir => tmp_file, :type => :single, :unnamed => true)
29
+ fff db
30
+ end
31
+ test = db.keys.sort{rand}[1..100000]
32
+ Misc.benchmark(5, "Access #{test.length} random entries") do
33
+ test.each do |k| db[k] end
34
+ end
35
+ Log.info "Profiling access to #{test.length} random entries"
36
+ Misc.profile :min_percent => 0.1 do
37
+ test.each do |k| db[k] end
38
+ end
39
+ assert_equal "1:10611:G", db["rs189107123"]
40
+ end
41
+ end
42
+
43
+ def test_benchmark_tch
44
+ engine = "HDB"
45
+ run_bechmark(tsv_path, engine)
46
+ end
47
+
48
+ def test_benchmark_tcb
49
+ engine = "BDB"
50
+ run_bechmark(tsv_path, engine)
51
+ end
52
+
53
+ def test_benchmark_kch
54
+ engine = "kch"
55
+ run_bechmark(tsv_path, engine)
56
+ end
57
+
58
+ def test_benchmark_kcb
59
+ engine = "kct"
60
+ run_bechmark(tsv_path, engine)
61
+ end
62
+
63
+ def test_benchmark_cdb
64
+ engine = "CDB"
65
+ run_bechmark(tsv_path, engine)
66
+ end
67
+
68
+ def test_benchmark_leveldb
69
+ engine = "LevelDB"
70
+ run_bechmark(tsv_path, engine)
71
+ end
72
+
73
+ def __test_benchmark_lmdb
74
+ engine = "LMDB"
75
+ run_bechmark(tsv_path, engine)
76
+ end
77
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+ require 'rbbt/persist'
3
+ require 'rbbt/annotations'
4
+ require 'rbbt/util/tmpfile'
5
+ require 'test/unit'
6
+
7
+ module TestAnnotation
8
+ extend Annotation
9
+
10
+ self.annotation :test_annotation
11
+ end
12
+
13
+ class TestPersistTSVCDB < Test::Unit::TestCase
14
+
15
+ def test_organism
16
+ require 'rbbt/sources/organism'
17
+ TmpFile.with_file nil do |tmp_file|
18
+ file = CMD.cmd("head -n 1000000", :in => Organism.identifiers("Hsa").open, :pipe => true)
19
+ tsv = Organism.identifiers("Hsa").tsv(:key_field => "Associated Gene Name", :fields => ["Ensembl Gene ID"], :type => :single, :persist => true, :persist_engine => "CDB", :persist_dir => tmp_file)
20
+ assert_equal "ENSG00000141510", tsv["TP53"]
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+ require 'rbbt/persist'
3
+ require 'rbbt/persist/tsv'
4
+ require 'rbbt/annotations'
5
+ require 'rbbt/util/tmpfile'
6
+ require 'test/unit'
7
+
8
+ require 'rbbt/sources/organism'
9
+
10
+ module TestAnnotation
11
+ extend Annotation
12
+
13
+ self.annotation :test_annotation
14
+ end
15
+
16
+ class TestPersistTSVKC < Test::Unit::TestCase
17
+ def _test_organism_kch
18
+ require 'rbbt/sources/organism'
19
+ TmpFile.with_file do |tmp_file|
20
+ tsv = Organism.identifiers("Hsa").tsv :key_field => "Associated Gene Name", :fields => ["Ensembl Gene ID"], :type => :single, :persist => true, :persist_engine => "kch", :persist_dir => tmp_file
21
+ assert_equal "ENSG00000141510", tsv["TP53"]
22
+ end
23
+ end
24
+
25
+
26
+ def test_organism_kct
27
+ require 'rbbt/sources/organism'
28
+ TmpFile.with_file do |tmp_file|
29
+ tsv = Organism.identifiers("Hsa").tsv :key_field => "Associated Gene Name", :fields => ["Ensembl Gene ID"], :type => :single, :persist => true, :persist_engine => "kct", :persist_dir => tmp_file
30
+ assert_equal "ENSG00000141510", tsv["TP53"]
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+ require 'rbbt/persist'
3
+ require 'rbbt/annotations'
4
+ require 'rbbt/util/tmpfile'
5
+ require 'test/unit'
6
+
7
+ module TestAnnotation
8
+ extend Annotation
9
+
10
+ self.annotation :test_annotation
11
+ end
12
+
13
+ class TestPersistTSVLevelDB < Test::Unit::TestCase
14
+
15
+ def test_organism
16
+ require 'rbbt/sources/organism'
17
+ TmpFile.with_file do |tmp_file|
18
+ tsv = Organism.identifiers("Hsa").tsv :key_field => "Associated Gene Name", :fields => ["Ensembl Gene ID"], :type => :single, :persist => true, :persist_engine => "LevelDB", :persist_dir => tmp_file
19
+ assert_equal "ENSG00000141510", tsv["TP53"]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+ require 'rbbt/persist'
3
+ require 'rbbt/annotations'
4
+ require 'rbbt/util/tmpfile'
5
+ require 'test/unit'
6
+
7
+ module TestAnnotation
8
+ extend Annotation
9
+
10
+ self.annotation :test_annotation
11
+ end
12
+
13
+ class TestPersistTSVLMDB < Test::Unit::TestCase
14
+
15
+ def test_organism
16
+ require 'rbbt/sources/organism'
17
+ TmpFile.with_file do |tmp_file|
18
+ tsv = Organism.identifiers("Hsa").tsv :key_field => "Associated Gene Name", :fields => ["Ensembl Gene ID"], :type => :single, :persist => true, :persist_engine => "LMDB", :persist_dir => tmp_file
19
+ assert_equal "ENSG00000141510", tsv["TP53"]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,242 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+ require 'rbbt/persist'
3
+ require 'rbbt/annotations'
4
+ require 'rbbt/util/tmpfile'
5
+ require 'test/unit'
6
+
7
+ module TestAnnotation
8
+ extend Annotation
9
+
10
+ self.annotation :test_annotation
11
+ end
12
+
13
+ class TestPersistTSVTC < Test::Unit::TestCase
14
+
15
+ def test_organism
16
+ require 'rbbt/sources/organism'
17
+ TmpFile.with_file do |tmp_file|
18
+ tsv = Organism.identifiers("Hsa").tsv :key_field => "Associated Gene Name", :fields => ["Ensembl Gene ID"], :type => :single, :persist => true, :persist_engine => "HDB", :persist_dir => tmp_file
19
+ assert_equal "ENSG00000141510", tsv["TP53"]
20
+ end
21
+ end
22
+
23
+ def test_annotation_persist
24
+ TmpFile.with_file do |tmp|
25
+ entity1 = "Entity 1"
26
+ entity2 = "Entity 2"
27
+
28
+ TestAnnotation.setup(entity1, :test_annotation => "1")
29
+ TestAnnotation.setup(entity2, :test_annotation => "2")
30
+
31
+ annotations = [entity1, entity2]
32
+
33
+ persisted_annotations = Persist.persist("Test", :annotations, :file => tmp) do
34
+ annotations
35
+ end
36
+
37
+ assert_equal "Entity 1", persisted_annotations.first
38
+ assert_equal "Entity 2", persisted_annotations.last
39
+ assert_equal "1", persisted_annotations.first.test_annotation
40
+ assert_equal "2", persisted_annotations.last.test_annotation
41
+
42
+ persisted_annotations = Persist.persist("Test", :annotations, :file => tmp) do
43
+ annotations
44
+ end
45
+
46
+ assert_equal "Entity 1", persisted_annotations.sort.first
47
+ assert_equal "Entity 2", persisted_annotations.sort.last
48
+ assert_equal "1", persisted_annotations.sort.first.test_annotation
49
+ assert_equal "2", persisted_annotations.sort.last.test_annotation
50
+ end
51
+ end
52
+
53
+ def test_annotation_persist_with_repeitions
54
+ TmpFile.with_file do |tmp|
55
+ entity1 = "Entity 1"
56
+ entity2 = "Entity 2"
57
+ entity2bis = "Entity 2"
58
+
59
+ TestAnnotation.setup(entity1, :test_annotation => "1")
60
+ TestAnnotation.setup(entity2, :test_annotation => "2")
61
+ TestAnnotation.setup(entity2bis, :test_annotation => "2")
62
+
63
+ annotations = [entity1, entity2, entity2bis]
64
+
65
+ persisted_annotations = Persist.persist("Test", :annotations, :file => tmp) do
66
+ annotations
67
+ end
68
+
69
+ assert_equal 3, persisted_annotations.length
70
+
71
+ assert_equal "Entity 1", persisted_annotations.first
72
+ assert_equal "Entity 2", persisted_annotations.last
73
+ assert_equal "1", persisted_annotations.first.test_annotation
74
+ assert_equal "2", persisted_annotations.last.test_annotation
75
+
76
+ persisted_annotations = Persist.persist("Test", :annotations, :file => tmp) do
77
+ annotations
78
+ end
79
+
80
+ assert_equal 3, persisted_annotations.length
81
+
82
+ assert_equal "Entity 1", persisted_annotations.sort.first
83
+ assert_equal "Entity 2", persisted_annotations.sort.last
84
+ assert_equal "1", persisted_annotations.sort.first.test_annotation
85
+ assert_equal "2", persisted_annotations.sort.last.test_annotation
86
+ end
87
+ end
88
+
89
+ def test_bdb
90
+ TmpFile.with_file do |tmp|
91
+ repo = Persist.open_tokyocabinet(tmp, true, :double, TokyoCabinet::BDB)
92
+ repo["test:string1"] = [["STR1"]]
93
+ repo["test:string2"] = [["STR2"]]
94
+ repo["other_test:string3"] = [["STR2"]]
95
+
96
+ assert_equal ["test:string1", "test:string2"].sort, repo.range("test:" << 0.chr, false, "test:" << 255.chr, false).sort
97
+ assert_equal ["other_test:string3"].sort, repo.range("other_test:" << 0.chr, false, "other_test:" << 255.chr, false).sort
98
+ end
99
+ end
100
+
101
+ def test_annotation_persist_repo
102
+ TmpFile.with_file do |tmp|
103
+ repo = Persist.open_tokyocabinet(tmp, true, :list, TokyoCabinet::BDB)
104
+
105
+ entity1 = "Entity 1"
106
+ entity2 = "Entity 2"
107
+
108
+ TestAnnotation.setup(entity1, :test_annotation => "1")
109
+ TestAnnotation.setup(entity2, :test_annotation => "2")
110
+
111
+ annotations = [entity1, entity2]
112
+
113
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
114
+ annotations
115
+ end
116
+
117
+ assert_equal "Entity 1", persisted_annotations.first
118
+ assert_equal "Entity 2", persisted_annotations.last
119
+ assert_equal "1", persisted_annotations.first.test_annotation
120
+ assert_equal "2", persisted_annotations.last.test_annotation
121
+
122
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
123
+ annotations
124
+ end
125
+
126
+ assert_equal "Entity 1", persisted_annotations.sort.first
127
+ assert_equal "Entity 2", persisted_annotations.sort.last
128
+ assert_equal "1", persisted_annotations.sort.first.test_annotation
129
+ assert_equal "2", persisted_annotations.sort.last.test_annotation
130
+ end
131
+ end
132
+
133
+ def test_annotation_persist_repo_annotated_array
134
+ TmpFile.with_file do |tmp|
135
+ repo = Persist.open_tokyocabinet(tmp, true, :list, TokyoCabinet::BDB)
136
+
137
+ entity1 = "Entity 1"
138
+ entity2 = "Entity 2"
139
+
140
+ annotations = [entity1, entity2]
141
+ TestAnnotation.setup(annotations, :test_annotation => "1")
142
+ annotations.extend AnnotatedArray
143
+
144
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
145
+ annotations
146
+ end
147
+
148
+ assert_equal "Entity 1", persisted_annotations.first
149
+ assert_equal "Entity 2", persisted_annotations.last
150
+ assert_equal "1", persisted_annotations.first.test_annotation
151
+ assert_equal "1", persisted_annotations.last.test_annotation
152
+
153
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
154
+ annotations
155
+ end
156
+
157
+ persisted_annotations.extend AnnotatedArray
158
+
159
+ assert_equal "Entity 1", persisted_annotations.sort.first
160
+ assert_equal "Entity 2", persisted_annotations.sort.last
161
+ assert_equal "1", persisted_annotations.sort.first.test_annotation
162
+ assert_equal "1", persisted_annotations.sort.last.test_annotation
163
+ end
164
+ end
165
+
166
+ def test_annotation_persist_repo_triple_array
167
+ TmpFile.with_file(nil, false) do |tmp|
168
+ repo = Persist.open_database(tmp, true, :list, "BDB")
169
+
170
+ entity1 = "Entity 1"
171
+ entity2 = "Entity 2"
172
+
173
+ annotations = [entity1, entity2]
174
+ TestAnnotation.setup(annotations, :test_annotation => "1")
175
+ annotations.extend AnnotatedArray
176
+
177
+ annotations_ary = [annotations]
178
+ TestAnnotation.setup(annotations_ary, :test_annotation => "1")
179
+ annotations_ary.extend AnnotatedArray
180
+
181
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
182
+ annotations_ary
183
+ end
184
+ assert AnnotatedArray === persisted_annotations
185
+
186
+ assert_equal "Entity 1", persisted_annotations.first.first
187
+ assert_equal "Entity 2", persisted_annotations.first.last
188
+ assert_equal "1", persisted_annotations.first.first.test_annotation
189
+ assert_equal "1", persisted_annotations.first.last.test_annotation
190
+
191
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
192
+ annotations_ary
193
+ end
194
+
195
+ assert AnnotatedArray === persisted_annotations
196
+
197
+ assert_equal "Entity 1", persisted_annotations.sort.first.first
198
+ assert_equal "Entity 2", persisted_annotations.sort.first.last
199
+ assert_equal "1", persisted_annotations.sort.first.first.test_annotation
200
+ assert_equal "1", persisted_annotations.sort.first.last.test_annotation
201
+
202
+ end
203
+ end
204
+
205
+ def test_annotation_persist_repo_with_repetitions
206
+ TmpFile.with_file do |tmp|
207
+ repo = Persist.open_tokyocabinet(tmp, true, :list, TokyoCabinet::BDB)
208
+
209
+ entity1 = "Entity 1"
210
+ entity2 = "Entity 2"
211
+ entity2bis = "Entity 2"
212
+
213
+ TestAnnotation.setup(entity1, :test_annotation => "1")
214
+ TestAnnotation.setup(entity2, :test_annotation => "2")
215
+ TestAnnotation.setup(entity2bis, :test_annotation => "2")
216
+
217
+ annotations = [entity1, entity2, entity2bis]
218
+
219
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
220
+ annotations
221
+ end
222
+
223
+ assert_equal 3, persisted_annotations.length
224
+
225
+ assert_equal "Entity 1", persisted_annotations.first
226
+ assert_equal "Entity 2", persisted_annotations.last
227
+ assert_equal "1", persisted_annotations.first.test_annotation
228
+ assert_equal "2", persisted_annotations.last.test_annotation
229
+
230
+ persisted_annotations = Persist.persist("Test", :annotations, :annotation_repo => repo) do
231
+ annotations
232
+ end
233
+
234
+ assert_equal 3, persisted_annotations.length
235
+
236
+ assert_equal "Entity 1", persisted_annotations.sort.first
237
+ assert_equal "Entity 2", persisted_annotations.sort.last
238
+ assert_equal "1", persisted_annotations.sort.first.test_annotation
239
+ assert_equal "2", persisted_annotations.sort.last.test_annotation
240
+ end
241
+ end
242
+ end