roqua-csv_export 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4a79aadf9c4962f616080afd55cf135bc0cb2e6dbf434f39a4503bcf33059561
4
+ data.tar.gz: e0b88f7020f55e3d66987bd847360648e1cf49f0ade702455878452978ac466e
5
+ SHA512:
6
+ metadata.gz: 6e933d46c4d967409656f0498ce46daee0f61a50222d0d9587283fa411e8d7dc7753170d12c5ff825e93850306a20196776be5f734cd3e5fbcdcc774a61e05b9
7
+ data.tar.gz: f7d8c837215327291c4622a1608a7bcc5cf836d3936c4cafb86aa98fd92fec4d56280f3f2b46059cac45d7cf93c5083fb9f515fe8d4f2ac21b23aae62c4e4ef7
@@ -0,0 +1,44 @@
1
+ # Roqua CSV export from sqlite export
2
+
3
+ ## Description
4
+
5
+ Takes a sqlite export and some export_version definitions and generates a csv file for each questionnaire in each version.
6
+
7
+ ## Examples
8
+
9
+ ```ruby
10
+ require 'roqua-csv_export'
11
+ Roqua::CsvExport.generate sqlite_path: Pathname.new('spec/fixtures/sql_export.db'),
12
+ export_versions_path: Pathname.new('spec/fixtures/export_versions'),
13
+ output_path: Pathname.new('tmp/data_exports'),
14
+ organization_key: 'demo',
15
+ anonymous_data_in_exports: false # the default.
16
+ ```
17
+
18
+ See [generate method](docs/Roqua/CsvExport#generate-class_method)
19
+
20
+ ## Requirements
21
+
22
+ ## Install
23
+
24
+ $ gem install roqua-csv_export
25
+
26
+ ## Developing
27
+
28
+ * Download source
29
+ * run `bundle`
30
+ * run `guard`
31
+ * write your test and see them fail
32
+ * write your code until the spec pass.
33
+
34
+ ## Changelog
35
+
36
+ ### 0.1.0
37
+
38
+ First version.
39
+
40
+ ## Copyright
41
+
42
+ Copyright (c) 2017 Roqua
43
+
44
+ See {file:LICENSE.txt} for details.
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # encoding: utf-8
4
+
5
+ require 'rubygems'
6
+
7
+ begin
8
+ require 'bundler'
9
+ rescue LoadError => e
10
+ warn e.message
11
+ warn "Run `gem install bundler` to install Bundler."
12
+ exit(-1)
13
+ end
14
+
15
+ begin
16
+ Bundler.setup(:development)
17
+ rescue Bundler::BundlerError => e
18
+ warn e.message
19
+ warn "Run `bundle install` to install missing gems."
20
+ exit e.status_code
21
+ end
22
+
23
+ require 'rake'
24
+
25
+ require 'rspec/core/rake_task'
26
+ RSpec::Core::RakeTask.new
27
+
28
+ task test: :spec
29
+ task default: :spec
30
+
31
+ # run bundle in parent dir to update Gemfile.lock
32
+ task :release do
33
+ Bundler.with_clean_env do
34
+ `bundle --gemfile=../Gemfile`
35
+ end
36
+ `git add ../Gemfile.lock && git commit -m 'update roqua-csv_export in Gemfile.lock'`
37
+ end
38
+
39
+ require "bundler/gem_tasks"
40
+
41
+ require 'yard'
42
+ YARD::Rake::YardocTask.new
43
+ task doc: :yard
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ::File.expand_path('../roqua/csv_export', __FILE__)
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext/object'
5
+ require 'sequel'
6
+ require 'roqua/csv_export/version'
7
+ require 'roqua/csv_export/models'
8
+
9
+ module Roqua
10
+ module CsvExport
11
+ extend ActiveSupport::Autoload
12
+
13
+ autoload :CsvExportQuestionnaireVersion
14
+ autoload :ExportVersions
15
+ autoload :MetaData
16
+ autoload :Config
17
+
18
+ DB = Sequel.sqlite
19
+
20
+ # Generate te export files.
21
+ # When done, output_path will contain a directory for each export_version.
22
+ # Each directory will contain csv file for each questionnare.
23
+ # @see Config#initialize Config for list of attributes
24
+ def self.generate(**attrs)
25
+ require 'csv'
26
+ require 'json'
27
+ config = Config.new(**attrs)
28
+ load_db(DB, config.sqlite_path)
29
+ create_indexes
30
+
31
+ FileUtils.mkdir_p config.output_path
32
+ do_export config.export_versions, config
33
+ end
34
+
35
+ private
36
+
37
+ def self.load_db(db, path)
38
+ source = SQLite3::Database.new(path.to_s)
39
+
40
+ db.synchronize do |memory_db|
41
+ backup = SQLite3::Backup.new(memory_db, 'main', source, 'main')
42
+ backup.step(-1)
43
+ backup.finish
44
+ end
45
+ ensure
46
+ source.close
47
+ end
48
+
49
+ def self.create_indexes
50
+ Sequel.extension :migration
51
+ Sequel.migration do
52
+ change do
53
+ alter_table(:responses) do
54
+ add_index :questionnaire_key
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def self.questionnaire_keys
61
+ Models::Response.distinct.select_map(:questionnaire_key)
62
+ end
63
+
64
+ def self.do_export(export_versions, config)
65
+ questionnaire_keys.each do |questionnaire_key|
66
+ responses = CsvExport::Models::Response \
67
+ .eager(:dossier, :team, :entered_by, :respondent, :response_values, :response_flags, :response_textvars, :team, measurement: :protocol)
68
+ .where(questionnaire_key: questionnaire_key)
69
+ .order(:id)
70
+
71
+ CsvExportQuestionnaireVersion.with_versions_for(questionnaire_key,
72
+ config) do |versions|
73
+ responses.paged_each do |response|
74
+ versions.each do |version|
75
+ version.write_response(response)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport
4
+ # Configuration for an export run.
5
+ # Each argument to new has a corresponding getter, with export_versions using export_versions_path to load the data.
6
+ class Config
7
+ ATTRS = %i(sqlite_path
8
+ export_versions
9
+ export_versions_path
10
+ organization_key
11
+ output_path
12
+ anonymous_data_in_exports)
13
+
14
+ attr_reader *ATTRS
15
+
16
+ # @param sqlite_path [Pathname] full path to sql_export.db.
17
+ # @param export_versions [ExportVersions] the versions to export. Can pass path instead.
18
+ # @param export_versions_path [Pathname] path to directory with json files, to load export_versions from.
19
+ # @param organization_key [String] will be prepended to csv_file_names.
20
+ # @param output_path [Pathname] to write a directory per export_version to.
21
+ # @param anonymous_data_in_exports [Boolean] when true, external_identifier and respondent#id will be exported
22
+ # for anonymous responses.
23
+ def initialize(sqlite_path:,
24
+ export_versions: nil,
25
+ export_versions_path: nil,
26
+ organization_key:,
27
+ output_path:,
28
+ anonymous_data_in_exports: false)
29
+ local_variables.each do |attr|
30
+ instance_variable_set("@#{attr}", binding.local_variable_get(attr))
31
+ end
32
+ end
33
+
34
+ def export_versions
35
+ @export_versions ||= ::Roqua::CsvExport::ExportVersions.new(export_versions_path)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport
4
+ # Used to write a single csv file for one export_version of one questionnaire.
5
+ #
6
+ class CsvExportQuestionnaireVersion
7
+ attr_reader :config
8
+
9
+ # For each version in export_versions, call {.open}, yield the instances and {#close} them.
10
+ #
11
+ # @yield [questionnaire_versions]
12
+ # @yieldparam version [Array<CsvExportQuestionnaireVersion>]
13
+ # @return [void]
14
+ def self.with_versions_for(questionnaire_key, config)
15
+ versions = config.export_versions.keys.map do |export_version_key|
16
+ open export_version_key,
17
+ export_version_mapping: config.export_versions.mapping_for(questionnaire_key, export_version_key),
18
+ config: config
19
+ end.compact
20
+
21
+ yield versions
22
+
23
+ ensure
24
+
25
+ versions&.each do |version|
26
+ version.close
27
+ end
28
+ end
29
+
30
+ # Creates new object with given params and calls #open on it.
31
+ # @return [CsvExportQuestionnaireVersion]
32
+ def self.open(*args)
33
+ self.new(*args).tap do |questionnaire_version|
34
+ questionnaire_version.open
35
+ end
36
+ end
37
+
38
+ # @param export_version_key [String] used to build directory name.
39
+ # @param export_version_mapping [Array<Hash>] Information on each column for the csv file in order.
40
+ # @param config [Config]
41
+ # @see ExportVersions#[] ExportsVersions for format of mapping.
42
+ def initialize(export_version_key, export_version_mapping:, config:)
43
+ @config = config
44
+ @export_version_key = export_version_key
45
+ @export_version_mapping = export_version_mapping
46
+ end
47
+
48
+ # opens file to write and writes headers to it.
49
+ # @return [void]
50
+ def open
51
+ `mkdir -p #{export_version_path}`
52
+ @file = CSV.open(csv_path, "w", col_sep: ';', force_quotes: true)
53
+ @file << export_version_mapping.map { |column| column['header'] }
54
+ end
55
+
56
+ # write the respomse to the file in the format of export_version
57
+ # @param response [Models::Response]
58
+ def write_response(response)
59
+ file << export_version_mapping \
60
+ .map { |column| get_value(column, response) }
61
+ .map { |value| format(value) }
62
+ end
63
+
64
+ # close the file.
65
+ # @return [void]
66
+ def close
67
+ file.close
68
+ end
69
+
70
+ private
71
+
72
+ attr_reader :export_version_key,
73
+ :export_version_mapping,
74
+ :file
75
+
76
+ def export_version_path
77
+ config.output_path.join("#{config.organization_key}_#{export_version_key}")
78
+ end
79
+
80
+ def csv_path
81
+ # find questionnaire key for the export_version (should be added explicitly to export_version json)
82
+ path_key = export_version_mapping.find{ |m| m['key'] == 'completed_at'}['header'][0..-14]
83
+ export_version_path.join("#{path_key}_#{Time.now.strftime("%Y-%m-%d")}.csv")
84
+ end
85
+
86
+ def get_value(column, response)
87
+ case column['source_type']
88
+ when 'metadata' then MetaData.send(column['key'], response)
89
+ when 'variable' then response.variable(column['key'])
90
+ when 'score' then response.score(column['key'], column['sub_key'])
91
+ when 'flag' then response.flag(column['key']) == '1' ? 'true' : ''
92
+ when 'textvar' then response.textvar(column['key'])
93
+ end
94
+ end
95
+
96
+ def format(value)
97
+ case value
98
+ when Time, Date, DateTime
99
+ value.strftime("%d-%m-%Y %H:%M:%S")
100
+ when Hash
101
+ value.to_json
102
+ when String
103
+ value.tr("\r\n", ' ')
104
+ else
105
+ value
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ require 'json'
3
+
4
+ module Roqua::CsvExport
5
+ # Reads json files with export_version info and caches them.
6
+ class ExportVersions
7
+ def initialize(mapping_files_directory_path)
8
+ @base_dir = mapping_files_directory_path
9
+ @export_versions = {}
10
+ end
11
+
12
+ # Returns column information for specified version for each variable in each questionnaire.
13
+ #
14
+ # Each column_hash looks like:
15
+ # {"key": "tot",
16
+ # "sub_key": "other",
17
+ # "header": "all_quests_tot_o",
18
+ # "source_type": "score"}
19
+ # Where header is the header within the csv file.
20
+ #
21
+ # @return [Hash] !{"fields" => {"oq45" => [{column_hash}, ...}}
22
+ def [](key)
23
+ @export_versions[key] ||= ::JSON.parse(File.read(File.join(@base_dir, "#{key}.json")))
24
+ end
25
+
26
+ def dig(key, *keys)
27
+ self[key].dig(*keys)
28
+ end
29
+
30
+ # @return [Array<String>] all the available versions, sorted oldest first.
31
+ def keys
32
+ Dir["#{@base_dir}/*.json"].map {|f| File.basename(f, File.extname(f)) }.sort
33
+ end
34
+
35
+ # Returns mapping for the questionnaire.
36
+ # First tries given export_version_key, but if the questonnaires wasn't defined then yet,
37
+ # it finds the first export_version that did define it.
38
+ # @return [Array<Hash>]
39
+ # @see []
40
+ def mapping_for(questionnaire_key, export_version_key)
41
+ dig(export_version_key, 'fields', questionnaire_key) \
42
+ || keys.lazy
43
+ .reject { |key| key <= export_version_key }
44
+ .map { |key| dig(key, 'fields', questionnaire_key) }
45
+ .reject(&:nil?)
46
+ .first
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport
4
+ # For each metadata key in export_versions, define a function to get the value for it for a given response.
5
+ module MetaData
6
+ extend self
7
+
8
+ def anonymous(response)
9
+ response.anonymous ? 'anonymous' : ''
10
+ end
11
+
12
+ def birth_year(response)
13
+ nil # deprecated
14
+ end
15
+
16
+ def compl_by(response)
17
+ return nil unless response.completed_at
18
+ return nil if response.anonymous && response.entered_by&.external_identifier.nil?
19
+
20
+ response.entered_by&.external_identifier || response.dossier.external_identifier
21
+ end
22
+
23
+ def completed_at(response)
24
+ response.completed_at
25
+ end
26
+
27
+ def date(response)
28
+ response.observation_time
29
+ end
30
+
31
+ def emailed_at(response)
32
+ nil # deprecated
33
+ end
34
+
35
+ def gender(response)
36
+ nil #deprecated
37
+ end
38
+
39
+ def hide_pii_from_researchers(response)
40
+ response.hide_pii_from_researchers ? "hide" : "show"
41
+ end
42
+
43
+ def hide_values_from_professionals(response)
44
+ response.hide_values_from_professionals ? "hide" : "show"
45
+ end
46
+
47
+ def id(response)
48
+ response.id
49
+ end
50
+
51
+ def invited_at(response)
52
+ nil # deprecated
53
+ end
54
+
55
+ def location(response)
56
+ response.team&.name
57
+ end
58
+
59
+ def measurement(response)
60
+ response.measurement&.name
61
+ end
62
+
63
+ def non_response(response)
64
+ response.non_response&.id
65
+ end
66
+
67
+ def notes(response)
68
+ response.notes
69
+ end
70
+
71
+ def open_from(response)
72
+ response.open_from
73
+ end
74
+
75
+ def patient_id(response)
76
+ return nil if response.anonymous
77
+
78
+ response.dossier.external_identifier
79
+ end
80
+
81
+ def project(response)
82
+ nil # deprecated
83
+ end
84
+
85
+ def protocol(response)
86
+ response.measurement&.protocol&.name
87
+ end
88
+
89
+ def respondent_id(response)
90
+ return nil if response.anonymous
91
+
92
+ response.respondent&.id
93
+ end
94
+
95
+ def respondent_label(response)
96
+ response.respondent&.label || 'Medewerker'
97
+ end
98
+
99
+ def respondent_type(response)
100
+ response.respondent&.type || 'profess'
101
+ end
102
+
103
+ def roqua_id(response)
104
+ nil # deprecated
105
+ end
106
+
107
+ def started_at(response)
108
+ response.started_at
109
+ end
110
+
111
+ def variant(response)
112
+ response.questionnaire_variant
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua
4
+ module CsvExport
5
+ module Models
6
+ extend ActiveSupport::Autoload
7
+
8
+ autoload :Dossier
9
+ autoload :Measurement
10
+ autoload :NonResponse
11
+ autoload :Professional
12
+ autoload :Protocol
13
+ autoload :Respondent
14
+ autoload :Response
15
+ autoload :ResponseFlag
16
+ autoload :ResponseTextvar
17
+ autoload :ResponseValue
18
+ autoload :ResponseScore
19
+ autoload :Team
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Dossier < Sequel::Model
5
+ one_to_many :responses
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Measurement < Sequel::Model
5
+ many_to_one :protocol
6
+ one_to_many :responses
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class NonResponse < Sequel::Model
5
+ one_to_many :responses
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Professional < Sequel::Model
5
+ one_to_many :responses
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Protocol < Sequel::Model
5
+ one_to_many :measurements
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Respondent < Sequel::Model
5
+ one_to_many :responses
6
+
7
+ def label
8
+ super.presence || default_label
9
+ end
10
+
11
+ def default_label
12
+ case type
13
+ when 'patient' then "Patiënt"
14
+ when 'parent' then "1e Ouder"
15
+ when 'second_parent' then "2e Ouder"
16
+ when 'teacher' then "Leraar"
17
+ when 'caregiver' then "Mantelzorger"
18
+ when 'profess' then "Medewerker"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Response < Sequel::Model
5
+ many_to_one :dossier
6
+ many_to_one :measurement
7
+ many_to_one :questionnaire
8
+ many_to_one :team
9
+ many_to_one :entered_by, class: Professional
10
+ many_to_one :respondent
11
+ many_to_one :non_response
12
+ one_to_many :response_flags
13
+ one_to_many :response_scores
14
+ one_to_many :response_textvars
15
+ one_to_many :response_values
16
+
17
+ # List of answers to questions.
18
+ # @return [Hash{String=>String}] !{'v_1' => '3', ...}
19
+ def variable_hash
20
+ @variable_hash ||= response_values.each_with_object({}) do |response_value, hash|
21
+ hash[response_value.question_key] = response_value.data
22
+ end
23
+ end
24
+
25
+ # List of calculated scores.
26
+ # @return [Hash{String=>Hash{String}}] !{'tot' => {'value' => '15', ...}, ...}
27
+ def score_hash
28
+ @response_score_hash ||= response_scores.each_with_object({}) do |response_score, hash|
29
+ (hash[response_score.score_key] ||= {})[response_score.score_subkey] = response_score.data
30
+ end
31
+ end
32
+
33
+ # Get answer belonging to given key.
34
+ # @param key [String] e.g. "v_1"
35
+ # @return [String] The value for specified question_key
36
+ def variable(key)
37
+ variable_hash[key]
38
+ end
39
+
40
+ # Retrieve a score value. main value for a score will usually have sub_key "value".
41
+ # @param key [String] e.g. "tot"
42
+ # @param sub_key [String] e.g. "value" or "interpretation"
43
+ # @return [String]
44
+ def score(key, sub_key)
45
+ score_hash.dig(key, sub_key)
46
+ end
47
+
48
+ # @param key [String] prepended with questionnaire_key
49
+ # @return [String]
50
+ def flag(key)
51
+ response_flags.find { |response_flag| response_flag.key == key }.value
52
+ end
53
+
54
+ # @param key [String] prepended with questionnaire_key.
55
+ # @return [String]
56
+ def textvar(key)
57
+ response_textvars.find { |response_textvar| response_textvar.key == key }.value
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class ResponseFlag < Sequel::Model
5
+ many_to_one :response
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class ResponseScore < Sequel::Model
5
+ many_to_one :response
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class ResponseTextvar < Sequel::Model
5
+ many_to_one :response
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class ResponseValue < Sequel::Model
5
+ many_to_one :response
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua::CsvExport::Models
4
+ class Team < Sequel::Model
5
+ one_to_many :responses
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roqua
4
+ module CsvExport
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roqua-csv_export
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Henk van der Veen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: fabrication
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.9'
139
+ description: create csv exports from the sqlite export and the export_version json
140
+ email: henk.van.der.veen@gmail.com
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - README.md
146
+ - Rakefile
147
+ - lib/roqua-csv_export.rb
148
+ - lib/roqua/csv_export.rb
149
+ - lib/roqua/csv_export/config.rb
150
+ - lib/roqua/csv_export/csv_export_questionnaire_version.rb
151
+ - lib/roqua/csv_export/export_versions.rb
152
+ - lib/roqua/csv_export/meta_data.rb
153
+ - lib/roqua/csv_export/models.rb
154
+ - lib/roqua/csv_export/models/dossier.rb
155
+ - lib/roqua/csv_export/models/measurement.rb
156
+ - lib/roqua/csv_export/models/non_response.rb
157
+ - lib/roqua/csv_export/models/professional.rb
158
+ - lib/roqua/csv_export/models/protocol.rb
159
+ - lib/roqua/csv_export/models/respondent.rb
160
+ - lib/roqua/csv_export/models/response.rb
161
+ - lib/roqua/csv_export/models/response_flag.rb
162
+ - lib/roqua/csv_export/models/response_score.rb
163
+ - lib/roqua/csv_export/models/response_textvar.rb
164
+ - lib/roqua/csv_export/models/response_value.rb
165
+ - lib/roqua/csv_export/models/team.rb
166
+ - lib/roqua/csv_export/version.rb
167
+ homepage: https://docs.roqua.net
168
+ licenses:
169
+ - MIT
170
+ metadata:
171
+ yard.run: yri
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubygems_version: 3.0.3
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: create csv exports from the sqlite export
191
+ test_files: []