ncs_mdes_warehouse 0.1.0 → 0.1.1
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/CHANGELOG.md +21 -0
- data/lib/ncs_navigator/warehouse/cli.rb +3 -2
- data/lib/ncs_navigator/warehouse/configuration.rb +1 -1
- data/lib/ncs_navigator/warehouse/database_initializer.rb +25 -9
- data/lib/ncs_navigator/warehouse/transform_load.rb +16 -6
- data/lib/ncs_navigator/warehouse/transformers.rb +1 -0
- data/lib/ncs_navigator/warehouse/transformers/database.rb +18 -8
- data/lib/ncs_navigator/warehouse/transformers/sampling_units.rb +96 -0
- data/lib/ncs_navigator/warehouse/transformers/vdr_xml.rb +13 -1
- data/lib/ncs_navigator/warehouse/version.rb +1 -1
- data/ncs_mdes_warehouse.gemspec +3 -3
- data/spec/navigator.ini +2 -1
- data/spec/ncs_navigator/warehouse/configuration_spec.rb +3 -3
- data/spec/ncs_navigator/warehouse/transform_load_spec.rb +17 -0
- data/spec/ncs_navigator/warehouse/transformers/database_spec.rb +11 -4
- data/spec/ncs_navigator/warehouse/transformers/sampling_units_spec.rb +103 -0
- data/spec/ncs_navigator/warehouse/transformers/vdr_xml_spec.rb +34 -4
- data/spec/ncs_navigator/warehouse/xml_emitter_spec.rb +2 -2
- data/spec/test_samples.csv +2 -1
- metadata +41 -44
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
NCS Navigator MDES Warehouse History
|
2
2
|
====================================
|
3
3
|
|
4
|
+
0.1.1
|
5
|
+
-----
|
6
|
+
|
7
|
+
- Disable DataMapper's identity map during ETL. It caches created
|
8
|
+
records in memory without limit, so it brings the system to a crawl
|
9
|
+
when loading hundreds of thousands of records.
|
10
|
+
|
11
|
+
- Wrap each transformer in a transaction during ETL, and turn off
|
12
|
+
synchronous commits. This combination (not tried separately) gives
|
13
|
+
around a 10% speed boost.
|
14
|
+
|
15
|
+
- Loosen gem dependencies for compatibility with Rails 3.0.
|
16
|
+
|
17
|
+
- Add `Transformers::SamplingUnits` for generating PSU, SSU, and TSU
|
18
|
+
records from the runtime configuration. (#1602)
|
19
|
+
|
20
|
+
- Changed default log path to `/var/log/nubic/ncs/warehouse`. This is
|
21
|
+
parallel with the default configuration paths under `/etc`. (#1605)
|
22
|
+
|
23
|
+
- Improve error messages in `VdrXml.from_most_recent_file`. (#1604)
|
24
|
+
|
4
25
|
0.1.0
|
5
26
|
-----
|
6
27
|
|
@@ -43,7 +43,8 @@ module NcsNavigator::Warehouse
|
|
43
43
|
desc 'clone-working', 'Copies the contents of the working database to the reporting database'
|
44
44
|
def clone_working
|
45
45
|
db = DatabaseInitializer.new(configuration)
|
46
|
-
db.
|
46
|
+
db.set_up_repository(:both)
|
47
|
+
db.clone_working_to_reporting or exit(1)
|
47
48
|
end
|
48
49
|
|
49
50
|
desc 'emit-xml [FILENAME]', 'Generates the VDR submission XML'
|
@@ -74,7 +75,7 @@ DESC
|
|
74
75
|
|
75
76
|
success = TransformLoad.new(configuration).run
|
76
77
|
if success || options['force']
|
77
|
-
db.clone_working_to_reporting
|
78
|
+
db.clone_working_to_reporting or exit(1)
|
78
79
|
else
|
79
80
|
configuration.shell.say_line "There were errors during ETL. Reporting database not updated."
|
80
81
|
configuration.shell.say_line "See the log and the database table wh_transform_error for more details."
|
@@ -80,11 +80,7 @@ module NcsNavigator::Warehouse
|
|
80
80
|
#
|
81
81
|
# @return [void]
|
82
82
|
def replace_schema
|
83
|
-
|
84
|
-
log.info "Dropping everything in working schema"
|
85
|
-
::DataMapper.repository(:mdes_warehouse_working).adapter.
|
86
|
-
execute("DROP OWNED BY #{params(:working)['username']}")
|
87
|
-
shell.clear_line_then_say "Dropped everything in working schema.\n"
|
83
|
+
drop_all(:working)
|
88
84
|
|
89
85
|
shell.say "Loading MDES models..."
|
90
86
|
log.info "Initializing schema for MDES #{configuration.mdes.specification_version}"
|
@@ -98,11 +94,23 @@ module NcsNavigator::Warehouse
|
|
98
94
|
"Added #{configuration.models_module.mdes_order.size} MDES tables.\n")
|
99
95
|
end
|
100
96
|
|
97
|
+
def drop_all(which)
|
98
|
+
shell.say "Dropping everything in #{which} schema"
|
99
|
+
log.info "Dropping everything in #{which} schema"
|
100
|
+
::DataMapper.repository(:"mdes_warehouse_#{which}").adapter.
|
101
|
+
execute("DROP OWNED BY #{params(which)['username']}")
|
102
|
+
shell.clear_line_then_say "Dropped everything in #{which} schema.\n"
|
103
|
+
end
|
104
|
+
private :drop_all
|
105
|
+
|
101
106
|
##
|
102
107
|
# Replaces the reporting database with a clone of the working
|
103
108
|
# database. This method relies on the command line `pg_dump` and
|
104
|
-
# `pg_restore` commands.
|
109
|
+
# `pg_restore` commands. In addition, you must also have
|
110
|
+
# previously called {#set_up_repository} with `:both` as the
|
111
|
+
# argument.
|
105
112
|
#
|
113
|
+
# @return [true,false] whether the clone succeeded.
|
106
114
|
# @see Configuration#pg_bin_path
|
107
115
|
def clone_working_to_reporting
|
108
116
|
PostgreSQL::Pgpass.new.tap do |pgpass|
|
@@ -121,16 +129,24 @@ module NcsNavigator::Warehouse
|
|
121
129
|
configuration.pg_bin('pg_restore'),
|
122
130
|
pg_params(params(:reporting)),
|
123
131
|
'--schema', 'public',
|
124
|
-
'--clean',
|
125
132
|
'--dbname', params(:reporting)['database']
|
126
133
|
].flatten
|
127
134
|
|
135
|
+
drop_all(:reporting)
|
136
|
+
|
128
137
|
command = "#{escape_cmd dump_cmd} | #{escape_cmd restore_cmd}"
|
138
|
+
shell.say 'Cloning working schema into reporting schema...'
|
129
139
|
log.info('Cloning working schema into reporting schema')
|
130
140
|
log.debug("Clone command: #{command.inspect}")
|
131
141
|
unless system(command)
|
132
|
-
|
133
|
-
|
142
|
+
shell.clear_line_then_say(
|
143
|
+
"Clone from working to reporting failed. See above for detail.\n")
|
144
|
+
log.error('Clone failed.')
|
145
|
+
return false
|
146
|
+
else
|
147
|
+
shell.clear_line_then_say("Clone from working to reporting successful.\n")
|
148
|
+
log.info('Clone succeeded.')
|
149
|
+
return true
|
134
150
|
end
|
135
151
|
end
|
136
152
|
|
@@ -18,13 +18,23 @@ module NcsNavigator::Warehouse
|
|
18
18
|
def run
|
19
19
|
position = 0
|
20
20
|
@statuses = configuration.transformers.collect do |transformer|
|
21
|
-
::DataMapper.repository(:mdes_warehouse_working) do
|
21
|
+
::DataMapper.repository(:mdes_warehouse_working) do |repo|
|
22
|
+
# redefine identity map as a no-op so it doesn't cache
|
23
|
+
# anything. TODO: provide a patch to DataMapper that makes
|
24
|
+
# something like this an option.
|
25
|
+
def repo.identity_map(model); {}; end
|
26
|
+
|
22
27
|
build_status_for(transformer, position).tap do |status|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
TransformStatus.transaction do
|
29
|
+
if repo.adapter.to_s =~ /Postgres/
|
30
|
+
repo.adapter.execute("SET LOCAL synchronous_commit TO OFF")
|
31
|
+
end
|
32
|
+
begin
|
33
|
+
transformer.transform(status)
|
34
|
+
rescue => e
|
35
|
+
shell.say_line("\nTransform failed. (See log for more detail.)")
|
36
|
+
status.add_error("Transform failed. #{e.class}: #{e}.")
|
37
|
+
end
|
28
38
|
end
|
29
39
|
status.end_time = Time.now
|
30
40
|
unless status.save
|
@@ -13,6 +13,7 @@ module NcsNavigator::Warehouse
|
|
13
13
|
module Transformers
|
14
14
|
autoload :Database, 'ncs_navigator/warehouse/transformers/database'
|
15
15
|
autoload :EnumTransformer, 'ncs_navigator/warehouse/transformers/enum_transformer'
|
16
|
+
autoload :SamplingUnits, 'ncs_navigator/warehouse/transformers/sampling_units'
|
16
17
|
autoload :VdrXml, 'ncs_navigator/warehouse/transformers/vdr_xml'
|
17
18
|
end
|
18
19
|
end
|
@@ -287,13 +287,12 @@ module NcsNavigator::Warehouse::Transformers
|
|
287
287
|
#
|
288
288
|
# @return [void]
|
289
289
|
def produce_one_for_one(name, model, options={})
|
290
|
-
options[:on_unused] ||= on_unused_columns
|
291
290
|
options[:column_map] =
|
292
291
|
(options[:column_map] || {}).inject({}) { |h, (k, v)| h[k.to_s] = v.to_s; h }
|
293
|
-
options[:ignored_columns] =
|
294
|
-
(options[:ignored_columns] || []).collect(&:to_s) + ignored_columns
|
292
|
+
options[:ignored_columns] = (options[:ignored_columns] || []).collect(&:to_s)
|
295
293
|
|
296
|
-
record_producers <<
|
294
|
+
record_producers <<
|
295
|
+
OneForOneProducer.new(name, options.delete(:query), model, self, options)
|
297
296
|
end
|
298
297
|
end
|
299
298
|
|
@@ -308,11 +307,12 @@ module NcsNavigator::Warehouse::Transformers
|
|
308
307
|
##
|
309
308
|
# The class encapsulating one call to {DSL#produce_one_for_one}
|
310
309
|
class OneForOneProducer < RecordProducer
|
311
|
-
attr_reader :model, :options
|
310
|
+
attr_reader :model, :options, :dsl_host
|
312
311
|
|
313
|
-
def initialize(name, query, model, options)
|
312
|
+
def initialize(name, query, model, dsl_host, options)
|
314
313
|
super(name, query, self)
|
315
314
|
@model = model
|
315
|
+
@dsl_host = dsl_host
|
316
316
|
@options = options
|
317
317
|
end
|
318
318
|
|
@@ -321,9 +321,9 @@ module NcsNavigator::Warehouse::Transformers
|
|
321
321
|
# row as mapped by {#column_map}.
|
322
322
|
def convert_row(row)
|
323
323
|
col_map = column_map(row.members)
|
324
|
-
unused = row.members.collect(&:to_s) - col_map.keys -
|
324
|
+
unused = row.members.collect(&:to_s) - col_map.keys - ignored_columns
|
325
325
|
|
326
|
-
if
|
326
|
+
if on_unused == :fail && !unused.empty?
|
327
327
|
raise UnusedColumnsForModelError.new(unused)
|
328
328
|
end
|
329
329
|
model.new(
|
@@ -374,6 +374,16 @@ module NcsNavigator::Warehouse::Transformers
|
|
374
374
|
end
|
375
375
|
end
|
376
376
|
private :prefixed_property_name
|
377
|
+
|
378
|
+
def on_unused
|
379
|
+
options[:on_unused] || dsl_host.on_unused_columns
|
380
|
+
end
|
381
|
+
private :on_unused
|
382
|
+
|
383
|
+
def ignored_columns
|
384
|
+
options[:ignored_columns] + dsl_host.ignored_columns
|
385
|
+
end
|
386
|
+
private :ignored_columns
|
377
387
|
end
|
378
388
|
|
379
389
|
##
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'ncs_navigator/warehouse'
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module NcsNavigator::Warehouse::Transformers
|
6
|
+
##
|
7
|
+
# An enumerator that yields the sampling unit records implied by the
|
8
|
+
# current `NcsNavigator::Configuration`.
|
9
|
+
#
|
10
|
+
# @see Configuration#navigator
|
11
|
+
class SamplingUnits
|
12
|
+
include Enumerable
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
attr_reader :configuration
|
16
|
+
def_delegators :configuration, :shell, :log
|
17
|
+
|
18
|
+
def self.create_transformer(config)
|
19
|
+
EnumTransformer.new(config, new(config))
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(config)
|
23
|
+
@configuration = config
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
log.info("Generating MDES records for sampling units.")
|
28
|
+
|
29
|
+
shell_describe('PSU', configuration.navigator.psus.size)
|
30
|
+
configuration.navigator.psus.each do |nav_psu|
|
31
|
+
yield create_psu(nav_psu)
|
32
|
+
end
|
33
|
+
|
34
|
+
shell_describe('SSU', configuration.navigator.ssus.size)
|
35
|
+
configuration.navigator.ssus.each do |nav_ssu|
|
36
|
+
yield create_ssu(nav_ssu)
|
37
|
+
end
|
38
|
+
|
39
|
+
tsus = configuration.navigator.ssus.collect { |nav_ssu| nav_ssu.tsus }.flatten
|
40
|
+
shell_describe('TSU', tsus.size)
|
41
|
+
tsus.each do |nav_tsu|
|
42
|
+
yield create_tsu(nav_tsu)
|
43
|
+
end
|
44
|
+
|
45
|
+
log.info("All sampling unit records generated.")
|
46
|
+
shell.clear_line_then_say("All sampling unit records generated.\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def shell_describe(what, count)
|
52
|
+
plural = ('s' if count != 1)
|
53
|
+
shell.clear_line_then_say("Generating MDES record#{plural} for #{count} #{what}#{plural}")
|
54
|
+
end
|
55
|
+
|
56
|
+
def psu_model
|
57
|
+
configuration.models_module.const_get(:Psu)
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_psu(nav_psu)
|
61
|
+
psu_model.new(
|
62
|
+
:psu_id => nav_psu.id,
|
63
|
+
:sc_id => configuration.navigator.sc_id,
|
64
|
+
:recruit_type => configuration.navigator.recruitment_type_id,
|
65
|
+
:psu_name => configuration.mdes.types.detect { |t| t.name == 'psu_cl1' }.code_list.
|
66
|
+
detect { |code| code.value == nav_psu.id }.label
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def ssu_model
|
71
|
+
configuration.models_module.const_get(:Ssu)
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_ssu(nav_ssu)
|
75
|
+
ssu_model.new(
|
76
|
+
:ssu_id => nav_ssu.id,
|
77
|
+
:ssu_name => nav_ssu.name,
|
78
|
+
:psu_id => nav_ssu.psu.id,
|
79
|
+
:sc_id => configuration.navigator.sc_id
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
def tsu_model
|
84
|
+
configuration.models_module.const_get(:Tsu)
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_tsu(nav_tsu)
|
88
|
+
tsu_model.new(
|
89
|
+
:tsu_id => nav_tsu.id,
|
90
|
+
:tsu_name => nav_tsu.name,
|
91
|
+
:psu_id => nav_tsu.ssu.psu.id,
|
92
|
+
:sc_id => configuration.navigator.sc_id
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -13,12 +13,24 @@ module NcsNavigator::Warehouse::Transformers
|
|
13
13
|
end
|
14
14
|
|
15
15
|
##
|
16
|
+
# @param config [Configuration] the configuration for the
|
17
|
+
# warehouse.
|
18
|
+
# @param list [String,Array<String>] the files to consider. This
|
19
|
+
# may be either a glob or an explicit list of files.
|
20
|
+
#
|
16
21
|
# @return [#transform] a transformer for the most recently
|
17
22
|
# modified VDR XML file from the given list of files.
|
18
23
|
def from_most_recent_file(config, list)
|
24
|
+
files =
|
25
|
+
if String === list
|
26
|
+
Dir[list].tap { |a| fail "Glob #{list} does not match any files." if a.empty? }
|
27
|
+
else
|
28
|
+
list.tap { |a| fail "The file list is empty." if a.empty? }
|
29
|
+
end
|
30
|
+
|
19
31
|
from_file(
|
20
32
|
config,
|
21
|
-
|
33
|
+
files.collect { |fn| [fn, File.stat(fn).mtime] }.
|
22
34
|
sort_by { |fn, mtime| mtime }.reverse.first.first)
|
23
35
|
end
|
24
36
|
end
|
data/ncs_mdes_warehouse.gemspec
CHANGED
@@ -16,16 +16,16 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.require_paths = ["lib", "generated_models"]
|
17
17
|
|
18
18
|
s.add_dependency 'ncs_mdes', '~> 0.4', '>= 0.4.2'
|
19
|
-
s.add_dependency 'ncs_navigator_configuration', '~> 0.
|
19
|
+
s.add_dependency 'ncs_navigator_configuration', '~> 0.2'
|
20
20
|
|
21
21
|
s.add_dependency 'activesupport', '~> 3.0'
|
22
|
-
s.add_dependency 'i18n', '~> 0.
|
22
|
+
s.add_dependency 'i18n', '~> 0.4' # required by activesupport
|
23
23
|
|
24
24
|
s.add_dependency 'thor', '~> 0.14.6'
|
25
25
|
s.add_dependency 'rubyzip', '~> 0.9.4'
|
26
26
|
|
27
27
|
s.add_dependency 'nokogiri', '~> 1.5.0'
|
28
|
-
s.add_dependency 'builder', '
|
28
|
+
s.add_dependency 'builder', '>= 2.1.2'
|
29
29
|
|
30
30
|
s.add_dependency 'data_mapper', '~> 1.2.0'
|
31
31
|
s.add_dependency 'bcdatabase', '~> 1.1'
|
data/spec/navigator.ini
CHANGED
@@ -157,8 +157,8 @@ module NcsNavigator::Warehouse
|
|
157
157
|
end
|
158
158
|
|
159
159
|
describe 'by default' do
|
160
|
-
it 'is /var/log/ncs/warehouse/{env_name}.log' do
|
161
|
-
config.log_file.to_s.should == '/var/log/ncs/warehouse/the_moon.log'
|
160
|
+
it 'is /var/log/nubic/ncs/warehouse/{env_name}.log' do
|
161
|
+
config.log_file.to_s.should == '/var/log/nubic/ncs/warehouse/the_moon.log'
|
162
162
|
end
|
163
163
|
|
164
164
|
it 'is a Pathname' do
|
@@ -187,7 +187,7 @@ module NcsNavigator::Warehouse
|
|
187
187
|
end
|
188
188
|
|
189
189
|
it 'reverts to the default' do
|
190
|
-
config.log_file.to_s.should == '/var/log/ncs/warehouse/the_moon.log'
|
190
|
+
config.log_file.to_s.should == '/var/log/nubic/ncs/warehouse/the_moon.log'
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
@@ -137,6 +137,23 @@ module NcsNavigator::Warehouse
|
|
137
137
|
|
138
138
|
it 'sends on failure'
|
139
139
|
end
|
140
|
+
|
141
|
+
# This is a crappy test; it would be better if it could be done
|
142
|
+
# another way. Unfortunately, it doesn't look like DataMapper
|
143
|
+
# exposes information to allow another way to check this.
|
144
|
+
it "defeats DataMapper's caching" do
|
145
|
+
seen_maps = []
|
146
|
+
identity_map_tracker_transformer = BlockTransformer.new { |s|
|
147
|
+
seen_maps << ::DataMapper::Repository.context.first.instance_eval { @identity_maps }
|
148
|
+
}
|
149
|
+
config.add_transformer(identity_map_tracker_transformer)
|
150
|
+
config.add_transformer(identity_map_tracker_transformer)
|
151
|
+
|
152
|
+
loader.run
|
153
|
+
loader.statuses.collect { |s| s.transform_errors }.flatten.should == []
|
154
|
+
|
155
|
+
seen_maps.should == [{}, {}]
|
156
|
+
end
|
140
157
|
end
|
141
158
|
|
142
159
|
class ::BlockTransformer
|
@@ -304,14 +304,15 @@ module NcsNavigator::Warehouse::Transformers
|
|
304
304
|
|
305
305
|
describe 'when #on_unused_columns is set to :fail' do
|
306
306
|
let(:cls) {
|
307
|
-
sample_class do
|
308
|
-
on_unused_columns :fail
|
307
|
+
sample_class.tap do |c|
|
308
|
+
c.on_unused_columns :fail
|
309
|
+
c.produce_one_for_one(:addresses, address_model, options)
|
309
310
|
end
|
310
311
|
}
|
311
312
|
|
312
313
|
it 'fails appropriately' do
|
313
314
|
begin
|
314
|
-
|
315
|
+
producer.call(make_row :address_type => '-5', :address_length => '6')
|
315
316
|
fail "Exception not thrown"
|
316
317
|
rescue Database::UnusedColumnsForModelError => e
|
317
318
|
e.unused.should == %w(address_length)
|
@@ -320,7 +321,13 @@ module NcsNavigator::Warehouse::Transformers
|
|
320
321
|
|
321
322
|
it 'does not fail if the global setting is overridden' do
|
322
323
|
options[:on_unused] = :ignore
|
323
|
-
lambda {
|
324
|
+
lambda { producer.call(make_row :address_type => '-5', :address_length => '6') }.
|
325
|
+
should_not raise_error
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'can be ignored by modifying the global setting' do
|
329
|
+
cls.on_unused_columns :ignore
|
330
|
+
lambda { producer.call(make_row :address_type => '-5', :address_length => '6') }.
|
324
331
|
should_not raise_error
|
325
332
|
end
|
326
333
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.expand_path('../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
module NcsNavigator::Warehouse::Transformers
|
4
|
+
describe SamplingUnits, :use_mdes, :slow do
|
5
|
+
subject { SamplingUnits.new(spec_config) }
|
6
|
+
|
7
|
+
let(:test_sc_id) { '20000029' }
|
8
|
+
let(:test_psu_id) { '20000030' }
|
9
|
+
|
10
|
+
describe '.create_transformer' do
|
11
|
+
it 'creates a transformer' do
|
12
|
+
SamplingUnits.create_transformer(spec_config).should respond_to(:transform)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'yields everything in MDES order' do
|
17
|
+
subject.to_a.collect { |i| i.class.to_s.demodulize }.should == %w(Psu Ssu Ssu Tsu)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'emitted PSU' do
|
21
|
+
let(:psu_model) { spec_config.models_module.const_get(:Psu) }
|
22
|
+
let(:psu) { subject.to_a.detect { |emitted| emitted.is_a?(psu_model) } }
|
23
|
+
|
24
|
+
it 'exists' do
|
25
|
+
psu.should_not be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'has the study center ID from the configuration' do
|
29
|
+
psu.sc_id.should == test_sc_id
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has the correct ID' do
|
33
|
+
psu.psu_id.should == test_psu_id
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has the name derived from the MDES' do
|
37
|
+
psu.psu_name.should == 'Cook County, IL (Wave 1)'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'uses the recruitment type from the configuration' do
|
41
|
+
psu.recruit_type.should == '3'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'emitted SSU set' do
|
46
|
+
let(:ssu_model) { spec_config.models_module.const_get(:Ssu) }
|
47
|
+
let(:ssus) { subject.to_a.select { |emitted| emitted.is_a?(ssu_model) } }
|
48
|
+
|
49
|
+
it 'includes all the SSUs from the configuration' do
|
50
|
+
ssus.collect(&:ssu_id).sort.should == %w(24 42)
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'an exemplar' do
|
54
|
+
let(:ssu) { ssus.detect { |s| s.ssu_id == '42' } }
|
55
|
+
|
56
|
+
it 'has the name' do
|
57
|
+
ssu.ssu_name.should == 'UPT-42'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'has the ID' do
|
61
|
+
ssu.ssu_id.should == '42'
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'has the SC ID' do
|
65
|
+
ssu.sc_id.should == '20000029'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'has the PSU ID' do
|
69
|
+
ssu.psu_id.should == test_psu_id
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'emitted TSU set' do
|
75
|
+
let(:tsu_model) { spec_config.models_module.const_get(:Tsu) }
|
76
|
+
let(:tsus) { subject.to_a.select { |emitted| emitted.is_a?(tsu_model) } }
|
77
|
+
|
78
|
+
it 'includes all the TSUs from the configuration' do
|
79
|
+
tsus.collect(&:tsu_id).sort.should == %w(42-3)
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'an exemplar' do
|
83
|
+
let(:tsu) { tsus.detect { |s| s.tsu_id == '42-3' } }
|
84
|
+
|
85
|
+
it 'has the name' do
|
86
|
+
tsu.tsu_name.should == 'UPT-42X'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'has the ID' do
|
90
|
+
tsu.tsu_id.should == '42-3'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'has the SC ID' do
|
94
|
+
tsu.sc_id.should == '20000029'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'has the PSU ID' do
|
98
|
+
tsu.psu_id.should == test_psu_id
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -27,7 +27,7 @@ module NcsNavigator::Warehouse::Transformers
|
|
27
27
|
|
28
28
|
describe '.from_most_recent_file' do
|
29
29
|
let(:path) { tmpdir('contractor-files') }
|
30
|
-
subject { VdrXml.from_most_recent_file(config,
|
30
|
+
subject { VdrXml.from_most_recent_file(config, list_or_glob) }
|
31
31
|
|
32
32
|
before do
|
33
33
|
system("touch -t 02030405 '#{path}/a'")
|
@@ -35,11 +35,41 @@ module NcsNavigator::Warehouse::Transformers
|
|
35
35
|
system("touch -t 02020405 '#{path}/c'")
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
describe 'with a file list' do
|
39
|
+
let(:list_or_glob) { Dir[File.join(path, '*')] }
|
40
|
+
|
41
|
+
it 'uses the most recent filename from the list' do
|
42
|
+
subject.enum.filename.should == File.join(path, 'b')
|
43
|
+
end
|
44
|
+
|
45
|
+
include_examples 'a VDR transformer'
|
46
|
+
|
47
|
+
describe 'that is empty' do
|
48
|
+
let(:list_or_glob) { [] }
|
49
|
+
|
50
|
+
it 'fails' do
|
51
|
+
lambda { subject }.should raise_error /The file list is empty./
|
52
|
+
end
|
53
|
+
end
|
40
54
|
end
|
41
55
|
|
42
|
-
|
56
|
+
describe 'with a glob' do
|
57
|
+
let(:list_or_glob) { File.join(path, '*') }
|
58
|
+
|
59
|
+
it 'uses the most recent filename matched by the glob' do
|
60
|
+
subject.enum.filename.should == File.join(path, 'b')
|
61
|
+
end
|
62
|
+
|
63
|
+
include_examples 'a VDR transformer'
|
64
|
+
|
65
|
+
describe 'when the glob does not match anything' do
|
66
|
+
let(:list_or_glob) { File.join(path, 'z*') }
|
67
|
+
|
68
|
+
it 'fails' do
|
69
|
+
lambda { subject }.should raise_error %r{Glob .*?./z\* does not match any files}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
43
73
|
end
|
44
74
|
end
|
45
75
|
end
|
@@ -23,11 +23,11 @@ module NcsNavigator::Warehouse
|
|
23
23
|
# Most of the details of the XML are tested on the MdesModel mixin
|
24
24
|
describe 'the generated XML', :slow do
|
25
25
|
it 'includes the SC from the configuration' do
|
26
|
-
xml.xpath('//sc_id').text.should == '
|
26
|
+
xml.xpath('//sc_id').text.should == '20000029'
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'includes the PSU from the configuration' do
|
30
|
-
xml.xpath('//psu_id').text.should == '
|
30
|
+
xml.xpath('//psu_id').text.should == '20000030'
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'includes the appropriate specification version' do
|
data/spec/test_samples.csv
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ncs_mdes_warehouse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-18 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ncs_mdes
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156621720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -24,21 +24,21 @@ dependencies:
|
|
24
24
|
version: 0.4.2
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2156621720
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: ncs_navigator_configuration
|
30
|
-
requirement: &
|
30
|
+
requirement: &2156620240 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '0.
|
35
|
+
version: '0.2'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2156620240
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: activesupport
|
41
|
-
requirement: &
|
41
|
+
requirement: &2156614960 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
44
|
- - ~>
|
@@ -46,21 +46,21 @@ dependencies:
|
|
46
46
|
version: '3.0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
|
-
version_requirements: *
|
49
|
+
version_requirements: *2156614960
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: i18n
|
52
|
-
requirement: &
|
52
|
+
requirement: &2156613720 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
54
54
|
requirements:
|
55
55
|
- - ~>
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: '0.
|
57
|
+
version: '0.4'
|
58
58
|
type: :runtime
|
59
59
|
prerelease: false
|
60
|
-
version_requirements: *
|
60
|
+
version_requirements: *2156613720
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: thor
|
63
|
-
requirement: &
|
63
|
+
requirement: &2156612920 !ruby/object:Gem::Requirement
|
64
64
|
none: false
|
65
65
|
requirements:
|
66
66
|
- - ~>
|
@@ -68,10 +68,10 @@ dependencies:
|
|
68
68
|
version: 0.14.6
|
69
69
|
type: :runtime
|
70
70
|
prerelease: false
|
71
|
-
version_requirements: *
|
71
|
+
version_requirements: *2156612920
|
72
72
|
- !ruby/object:Gem::Dependency
|
73
73
|
name: rubyzip
|
74
|
-
requirement: &
|
74
|
+
requirement: &2156612060 !ruby/object:Gem::Requirement
|
75
75
|
none: false
|
76
76
|
requirements:
|
77
77
|
- - ~>
|
@@ -79,10 +79,10 @@ dependencies:
|
|
79
79
|
version: 0.9.4
|
80
80
|
type: :runtime
|
81
81
|
prerelease: false
|
82
|
-
version_requirements: *
|
82
|
+
version_requirements: *2156612060
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: nokogiri
|
85
|
-
requirement: &
|
85
|
+
requirement: &2156611040 !ruby/object:Gem::Requirement
|
86
86
|
none: false
|
87
87
|
requirements:
|
88
88
|
- - ~>
|
@@ -90,21 +90,21 @@ dependencies:
|
|
90
90
|
version: 1.5.0
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
|
-
version_requirements: *
|
93
|
+
version_requirements: *2156611040
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: builder
|
96
|
-
requirement: &
|
96
|
+
requirement: &2156609980 !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
|
-
- -
|
99
|
+
- - ! '>='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: 2.1.2
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
|
-
version_requirements: *
|
104
|
+
version_requirements: *2156609980
|
105
105
|
- !ruby/object:Gem::Dependency
|
106
106
|
name: data_mapper
|
107
|
-
requirement: &
|
107
|
+
requirement: &2156609220 !ruby/object:Gem::Requirement
|
108
108
|
none: false
|
109
109
|
requirements:
|
110
110
|
- - ~>
|
@@ -112,10 +112,10 @@ dependencies:
|
|
112
112
|
version: 1.2.0
|
113
113
|
type: :runtime
|
114
114
|
prerelease: false
|
115
|
-
version_requirements: *
|
115
|
+
version_requirements: *2156609220
|
116
116
|
- !ruby/object:Gem::Dependency
|
117
117
|
name: bcdatabase
|
118
|
-
requirement: &
|
118
|
+
requirement: &2156608360 !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|
121
121
|
- - ~>
|
@@ -123,10 +123,10 @@ dependencies:
|
|
123
123
|
version: '1.1'
|
124
124
|
type: :runtime
|
125
125
|
prerelease: false
|
126
|
-
version_requirements: *
|
126
|
+
version_requirements: *2156608360
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: dm-postgres-adapter
|
129
|
-
requirement: &
|
129
|
+
requirement: &2156607420 !ruby/object:Gem::Requirement
|
130
130
|
none: false
|
131
131
|
requirements:
|
132
132
|
- - ~>
|
@@ -134,10 +134,10 @@ dependencies:
|
|
134
134
|
version: 1.2.0
|
135
135
|
type: :runtime
|
136
136
|
prerelease: false
|
137
|
-
version_requirements: *
|
137
|
+
version_requirements: *2156607420
|
138
138
|
- !ruby/object:Gem::Dependency
|
139
139
|
name: rspec
|
140
|
-
requirement: &
|
140
|
+
requirement: &2156606300 !ruby/object:Gem::Requirement
|
141
141
|
none: false
|
142
142
|
requirements:
|
143
143
|
- - ~>
|
@@ -145,10 +145,10 @@ dependencies:
|
|
145
145
|
version: '2.6'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
|
-
version_requirements: *
|
148
|
+
version_requirements: *2156606300
|
149
149
|
- !ruby/object:Gem::Dependency
|
150
150
|
name: rake
|
151
|
-
requirement: &
|
151
|
+
requirement: &2156604880 !ruby/object:Gem::Requirement
|
152
152
|
none: false
|
153
153
|
requirements:
|
154
154
|
- - ~>
|
@@ -156,10 +156,10 @@ dependencies:
|
|
156
156
|
version: 0.9.2
|
157
157
|
type: :development
|
158
158
|
prerelease: false
|
159
|
-
version_requirements: *
|
159
|
+
version_requirements: *2156604880
|
160
160
|
- !ruby/object:Gem::Dependency
|
161
161
|
name: yard
|
162
|
-
requirement: &
|
162
|
+
requirement: &2156603540 !ruby/object:Gem::Requirement
|
163
163
|
none: false
|
164
164
|
requirements:
|
165
165
|
- - ~>
|
@@ -167,10 +167,10 @@ dependencies:
|
|
167
167
|
version: 0.7.2
|
168
168
|
type: :development
|
169
169
|
prerelease: false
|
170
|
-
version_requirements: *
|
170
|
+
version_requirements: *2156603540
|
171
171
|
- !ruby/object:Gem::Dependency
|
172
172
|
name: ci_reporter
|
173
|
-
requirement: &
|
173
|
+
requirement: &2156602740 !ruby/object:Gem::Requirement
|
174
174
|
none: false
|
175
175
|
requirements:
|
176
176
|
- - ~>
|
@@ -178,10 +178,10 @@ dependencies:
|
|
178
178
|
version: 1.6.5
|
179
179
|
type: :development
|
180
180
|
prerelease: false
|
181
|
-
version_requirements: *
|
181
|
+
version_requirements: *2156602740
|
182
182
|
- !ruby/object:Gem::Dependency
|
183
183
|
name: fakefs
|
184
|
-
requirement: &
|
184
|
+
requirement: &2156601440 !ruby/object:Gem::Requirement
|
185
185
|
none: false
|
186
186
|
requirements:
|
187
187
|
- - ~>
|
@@ -189,7 +189,7 @@ dependencies:
|
|
189
189
|
version: 0.4.0
|
190
190
|
type: :development
|
191
191
|
prerelease: false
|
192
|
-
version_requirements: *
|
192
|
+
version_requirements: *2156601440
|
193
193
|
description:
|
194
194
|
email:
|
195
195
|
- r-sutphin@northwestern.edu
|
@@ -493,6 +493,7 @@ files:
|
|
493
493
|
- lib/ncs_navigator/warehouse/transformers.rb
|
494
494
|
- lib/ncs_navigator/warehouse/transformers/database.rb
|
495
495
|
- lib/ncs_navigator/warehouse/transformers/enum_transformer.rb
|
496
|
+
- lib/ncs_navigator/warehouse/transformers/sampling_units.rb
|
496
497
|
- lib/ncs_navigator/warehouse/transformers/vdr_xml.rb
|
497
498
|
- lib/ncs_navigator/warehouse/transformers/vdr_xml/reader.rb
|
498
499
|
- lib/ncs_navigator/warehouse/updating_shell.rb
|
@@ -512,6 +513,7 @@ files:
|
|
512
513
|
- spec/ncs_navigator/warehouse/transform_load_spec.rb
|
513
514
|
- spec/ncs_navigator/warehouse/transformers/database_spec.rb
|
514
515
|
- spec/ncs_navigator/warehouse/transformers/enum_transformer_spec.rb
|
516
|
+
- spec/ncs_navigator/warehouse/transformers/sampling_units_spec.rb
|
515
517
|
- spec/ncs_navigator/warehouse/transformers/vdr_xml/made_up_vdr_xml.xml
|
516
518
|
- spec/ncs_navigator/warehouse/transformers/vdr_xml/reader_spec.rb
|
517
519
|
- spec/ncs_navigator/warehouse/transformers/vdr_xml_spec.rb
|
@@ -532,18 +534,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
532
534
|
- - ! '>='
|
533
535
|
- !ruby/object:Gem::Version
|
534
536
|
version: '0'
|
535
|
-
segments:
|
536
|
-
- 0
|
537
|
-
hash: -4006681032861892905
|
538
537
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
539
538
|
none: false
|
540
539
|
requirements:
|
541
540
|
- - ! '>='
|
542
541
|
- !ruby/object:Gem::Version
|
543
542
|
version: '0'
|
544
|
-
segments:
|
545
|
-
- 0
|
546
|
-
hash: -4006681032861892905
|
547
543
|
requirements: []
|
548
544
|
rubyforge_project:
|
549
545
|
rubygems_version: 1.8.10
|
@@ -564,6 +560,7 @@ test_files:
|
|
564
560
|
- spec/ncs_navigator/warehouse/transform_load_spec.rb
|
565
561
|
- spec/ncs_navigator/warehouse/transformers/database_spec.rb
|
566
562
|
- spec/ncs_navigator/warehouse/transformers/enum_transformer_spec.rb
|
563
|
+
- spec/ncs_navigator/warehouse/transformers/sampling_units_spec.rb
|
567
564
|
- spec/ncs_navigator/warehouse/transformers/vdr_xml/made_up_vdr_xml.xml
|
568
565
|
- spec/ncs_navigator/warehouse/transformers/vdr_xml/reader_spec.rb
|
569
566
|
- spec/ncs_navigator/warehouse/transformers/vdr_xml_spec.rb
|