drupal-exporter 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +39 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +72 -0
- data/LICENSE +22 -0
- data/README.md +251 -0
- data/Rakefile +9 -0
- data/bin/drupal-exporter +37 -0
- data/drupal_exporter.gemspec +34 -0
- data/drupal_settings/boolean_columns.yml +2 -0
- data/drupal_settings/drupal_content_types.json +47 -0
- data/drupal_settings/drupal_settings.yml +23 -0
- data/lib/cli.rb +13 -0
- data/lib/configuration.rb +46 -0
- data/lib/converters/content_types_structure_creator.rb +60 -0
- data/lib/converters/contentful_model_to_json.rb +109 -0
- data/lib/drupal/content_type.rb +151 -0
- data/lib/drupal/export.rb +69 -0
- data/lib/drupal/file_managed.rb +42 -0
- data/lib/drupal/tag.rb +52 -0
- data/lib/drupal/user.rb +46 -0
- data/lib/drupal/vocabulary.rb +42 -0
- data/lib/migrator.rb +28 -0
- data/lib/version.rb +3 -0
- data/spec/fixtures/database_rows/content_type_article.json +14 -0
- data/spec/fixtures/database_rows/image.json +10 -0
- data/spec/fixtures/database_rows/node_content_type_article.json +15 -0
- data/spec/fixtures/database_rows/node_content_type_blog.json +15 -0
- data/spec/fixtures/database_rows/tag.json +8 -0
- data/spec/fixtures/database_rows/user.json +18 -0
- data/spec/fixtures/database_rows/vocabulary.json +9 -0
- data/spec/fixtures/drupal/assets/file/file_4.json +6 -0
- data/spec/fixtures/drupal/entries/article/article_5.json +24 -0
- data/spec/fixtures/drupal/entries/tag/tag_1.json +9 -0
- data/spec/fixtures/drupal/entries/user/user_1.json +6 -0
- data/spec/fixtures/drupal/entries/vocabulary/vocabulary_3.json +6 -0
- data/spec/fixtures/json_responses/article.json +24 -0
- data/spec/fixtures/json_responses/image.json +6 -0
- data/spec/fixtures/json_responses/tag.json +9 -0
- data/spec/fixtures/json_responses/vocabulary.json +6 -0
- data/spec/fixtures/settings/boolean_columns.yml +2 -0
- data/spec/fixtures/settings/drupal_content_types.json +47 -0
- data/spec/fixtures/settings/drupal_settings.yml +17 -0
- data/spec/lib/configuration_spec.rb +18 -0
- data/spec/lib/drupal/content_type_spec.rb +123 -0
- data/spec/lib/drupal/export_spec.rb +33 -0
- data/spec/lib/drupal/file_managed_spec.rb +52 -0
- data/spec/lib/drupal/tag_spec.rb +60 -0
- data/spec/lib/drupal/user_spec.rb +49 -0
- data/spec/lib/drupal/vocabulary_spec.rb +51 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/db_rows_json.rb +15 -0
- data/spec/support/shared_configuration.rb +20 -0
- metadata +297 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require File.expand_path('../lib/version', __FILE__)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'drupal-exporter'
|
8
|
+
spec.version = Version::VERSION
|
9
|
+
spec.authors = ['Contentful GmbH (Andreas Tiefenthaler)']
|
10
|
+
spec.email = ['rubygems@contentful.com']
|
11
|
+
spec.description = 'Drupal exporter that prepares content to be imported'
|
12
|
+
spec.summary = 'Exporter for Drupal 7'
|
13
|
+
spec.homepage = 'https://github.com/contentful/drupal-exporter.rb'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables << 'drupal-exporter'
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'http', '~> 0.6'
|
22
|
+
spec.add_dependency 'multi_json', '~> 1'
|
23
|
+
spec.add_dependency 'sequel','~> 4.15'
|
24
|
+
spec.add_dependency 'mysql2','~> 0.3'
|
25
|
+
spec.add_dependency 'activesupport','~> 4.1'
|
26
|
+
spec.add_dependency 'pg', '~> 0.17.0'
|
27
|
+
spec.add_dependency 'escort','~> 0.4.0'
|
28
|
+
spec.add_dependency 'i18n', '~> 0.6'
|
29
|
+
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3'
|
31
|
+
spec.add_development_dependency 'rspec-its', '~> 1.1.0'
|
32
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
33
|
+
spec.add_development_dependency 'rake'
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
// machine_name_of_content_type : {
|
2
|
+
// contentful_api_field : column_machine_name
|
3
|
+
// }
|
4
|
+
|
5
|
+
{
|
6
|
+
"article": {
|
7
|
+
"body": "body",
|
8
|
+
"image": "field_image"
|
9
|
+
},
|
10
|
+
"page": {
|
11
|
+
"body": "body"
|
12
|
+
},
|
13
|
+
"blog": {
|
14
|
+
"body": "body"
|
15
|
+
},
|
16
|
+
"content_type": {
|
17
|
+
"body": "body",
|
18
|
+
"age": "field_age",
|
19
|
+
"if_content_type": "field_if_content_type",
|
20
|
+
"decimal": "field_decimal"
|
21
|
+
},
|
22
|
+
"second_content_type": {
|
23
|
+
"body": "body",
|
24
|
+
"firma": "field_firma"
|
25
|
+
},
|
26
|
+
"content_all_types": {
|
27
|
+
"body": "body",
|
28
|
+
"file": "field_file",
|
29
|
+
"image_sec": "field_sec_image",
|
30
|
+
"integer": "field_integer",
|
31
|
+
"boolean": "field_boolean",
|
32
|
+
"decimal": "field_sec_decimal",
|
33
|
+
"list_float": "field_list_float",
|
34
|
+
"list_integer": "field_list_integer",
|
35
|
+
"list_text": "field_list_text",
|
36
|
+
"long_text": "field_long_text",
|
37
|
+
"text_summary": "field_text_summary",
|
38
|
+
"term_tagging": {
|
39
|
+
"table": "field_term_tagging"
|
40
|
+
},
|
41
|
+
"text": "field_text"
|
42
|
+
},
|
43
|
+
"assety": {
|
44
|
+
"body": "body",
|
45
|
+
"assets": "field_asset"
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#PATH to all data
|
2
|
+
data_dir: PATH_WHERE_ALL_DATA_WILL_BE_SAVED
|
3
|
+
|
4
|
+
########## EXPORT DATA ##########
|
5
|
+
|
6
|
+
#Connecting to a database
|
7
|
+
adapter: mysql2
|
8
|
+
host: localhost
|
9
|
+
database: drupal_database_name
|
10
|
+
user: username
|
11
|
+
password: password
|
12
|
+
|
13
|
+
# DRUPAL
|
14
|
+
|
15
|
+
drupal_content_types_json: drupal_settings/drupal_content_types.json
|
16
|
+
drupal_boolean_columns: drupal_settings/boolean_columns.yml
|
17
|
+
drupal_base_url: http://example_hostname.com
|
18
|
+
|
19
|
+
# CONVERT CONTENTFUL MODEL TO CONTENTFUL IMPORT STRUCTURE
|
20
|
+
content_model_json: PATH_TO_CONTENTFUL_MODEL_JSON_FILE
|
21
|
+
converted_model_dir: PATH_WHERE_CONVERTED_CONTENT_MODEL_WILL_BE_SAVED
|
22
|
+
|
23
|
+
contentful_structure_dir: PATH_TO_CONTENTFUL_STRUCUTRE_JSON_FILE
|
data/lib/cli.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'active_support/core_ext/hash'
|
3
|
+
|
4
|
+
module Contentful
|
5
|
+
class Configuration
|
6
|
+
attr_reader :space_id,
|
7
|
+
:config,
|
8
|
+
:data_dir,
|
9
|
+
:collections_dir,
|
10
|
+
:entries_dir,
|
11
|
+
:assets_dir,
|
12
|
+
:db,
|
13
|
+
:drupal_content_types,
|
14
|
+
:drupal_base_url
|
15
|
+
|
16
|
+
def initialize(settings)
|
17
|
+
@config = settings
|
18
|
+
validate_required_parameters
|
19
|
+
@data_dir = config['data_dir']
|
20
|
+
@collections_dir = "#{data_dir}/collections"
|
21
|
+
@entries_dir = "#{data_dir}/entries"
|
22
|
+
@assets_dir = "#{data_dir}/assets"
|
23
|
+
@space_id = config['space_id']
|
24
|
+
@drupal_content_types = JSON.parse(File.read(config['drupal_content_types_json']), symbolize_names: true).with_indifferent_access
|
25
|
+
@drupal_base_url = config['drupal_base_url']
|
26
|
+
@db = adapter_setup
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate_required_parameters
|
30
|
+
fail ArgumentError, 'Set PATH to data_dir, the destination for all generated files. Check README' if config['data_dir'].nil?
|
31
|
+
fail ArgumentError, 'Set PATH to drupal_content_types_json. File with Drupal database structure. View README' if config['drupal_content_types_json'].nil?
|
32
|
+
define_adapter
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_adapter
|
36
|
+
%w(adapter user host database).each do |param|
|
37
|
+
fail ArgumentError, "Set database connection parameters [adapter, host, database, user, password]. Missing the '#{param}' parameter! Password is optional. Check README!" unless config[param]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def adapter_setup
|
42
|
+
Sequel.connect(:adapter => config['adapter'], :user => config['user'], :host => config['host'], :database => config['database'], :password => config['password'])
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Contentful
|
2
|
+
module Converter
|
3
|
+
class ContentTypesStructureCreator
|
4
|
+
|
5
|
+
attr_reader :config, :logger
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
@logger = Logger.new(STDOUT)
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_content_type_json_file(content_type_name, values)
|
13
|
+
collection = {
|
14
|
+
id: values[:id],
|
15
|
+
name: values[:name],
|
16
|
+
description: values[:description],
|
17
|
+
displayField: values[:displayField],
|
18
|
+
fields: create_fields(values[:fields])
|
19
|
+
}
|
20
|
+
write_json_to_file("#{config.collections_dir}/#{content_type_name}.json", collection)
|
21
|
+
logger.info "Saving #{content_type_name}.json to #{config.collections_dir}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_fields(fields)
|
25
|
+
fields.each_with_object([]) do |(field, value), results|
|
26
|
+
results << {
|
27
|
+
name: create_field(field, value).capitalize,
|
28
|
+
id: create_field(field, value),
|
29
|
+
type: create_type_field(value),
|
30
|
+
link_type: create_link_type_field(value),
|
31
|
+
link: create_link_field(value)
|
32
|
+
}.compact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_field(field, value)
|
37
|
+
value.is_a?(Hash) ? value[:id] : field
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_link_type_field(value)
|
41
|
+
value.is_a?(Hash) ? value[:link_type] : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_type_field(value)
|
45
|
+
value.is_a?(Hash) ? value[:type] : value
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_link_field(value)
|
49
|
+
value.is_a?(Hash) ? value[:link] : nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def write_json_to_file(path, data)
|
53
|
+
File.open(path, 'w') do |file|
|
54
|
+
file.write(JSON.pretty_generate(data))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require_relative 'content_types_structure_creator'
|
2
|
+
|
3
|
+
module Contentful
|
4
|
+
module Converter
|
5
|
+
class ContentfulModelToJson
|
6
|
+
attr_reader :config, :logger, :converted_model_dir, :content_types
|
7
|
+
|
8
|
+
FIELD_TYPE = %w( Link Array )
|
9
|
+
|
10
|
+
def initialize(settings)
|
11
|
+
@config = settings
|
12
|
+
@logger = Logger.new(STDOUT)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_content_type_json
|
16
|
+
contentful_structure = load_contentful_structure_file
|
17
|
+
logger.info 'Create JSON files with content types structure...'
|
18
|
+
contentful_structure.each do |content_type, values|
|
19
|
+
content_type_name = content_type_name(content_type)
|
20
|
+
create_directory(config.collections_dir)
|
21
|
+
ContentTypesStructureCreator.new(config).create_content_type_json_file(content_type_name, values)
|
22
|
+
end
|
23
|
+
logger.info 'Done!'
|
24
|
+
end
|
25
|
+
|
26
|
+
def convert_to_import_form
|
27
|
+
set_content_model_parameters
|
28
|
+
logger.info 'Converting Contentful model to Contentful import structure...'
|
29
|
+
File.open(converted_model_dir, 'w') { |file| file.write({}) }
|
30
|
+
content_type_file = JSON.parse(File.read(content_types))['items']
|
31
|
+
content_type_file.each do |content_type|
|
32
|
+
parsed_content_type = {
|
33
|
+
id: content_type['sys']['id'],
|
34
|
+
name: content_type['name'],
|
35
|
+
description: content_type['description'],
|
36
|
+
displayField: content_type['displayField'],
|
37
|
+
fields: create_content_type_fields(content_type)
|
38
|
+
}
|
39
|
+
import_form = JSON.parse(File.read(converted_model_dir))
|
40
|
+
File.open(converted_model_dir, 'w') do |file|
|
41
|
+
file.write(JSON.pretty_generate(import_form.merge!(content_type['name'] => parsed_content_type)))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
logger.info "Done! Contentful import structure file saved in #{converted_model_dir}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_content_type_fields(content_type)
|
48
|
+
content_type['fields'].each_with_object({}) do |(field, _value), results|
|
49
|
+
id = link_id(field)
|
50
|
+
results[id] = case field['type']
|
51
|
+
when 'Link'
|
52
|
+
{id: field['id'], type: field['linkType'], link: 'Link'}
|
53
|
+
when 'Array'
|
54
|
+
{id: field['id'], type: field['type'], link_type: field['items']['linkType'], link: field['items']['type']}
|
55
|
+
else
|
56
|
+
field['type']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def link_id(field)
|
62
|
+
if FIELD_TYPE.include? field['type']
|
63
|
+
field['name'].capitalize
|
64
|
+
else
|
65
|
+
field['id']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def content_type_name(content_type)
|
70
|
+
I18n.transliterate(content_type).underscore.tr(' ', '_')
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_directory(path)
|
74
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
75
|
+
end
|
76
|
+
|
77
|
+
# If contentful_structure JSON file exists, it will load the file. If not, it will automatically create an empty file.
|
78
|
+
# This file is required to convert contentful model to contentful import structure.
|
79
|
+
def load_contentful_structure_file
|
80
|
+
fail ArgumentError, 'Set PATH for contentful structure JSON file. View README' if config.config['contentful_structure_dir'].nil?
|
81
|
+
file_exists? ? load_existing_contentful_structure_file : create_empty_contentful_structure_file
|
82
|
+
end
|
83
|
+
|
84
|
+
def file_exists?
|
85
|
+
File.exists?(config.config['contentful_structure_dir'])
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_empty_contentful_structure_file
|
89
|
+
File.open(config.config['contentful_structure_dir'], 'w') { |file| file.write({}) }
|
90
|
+
load_existing_contentful_structure_file
|
91
|
+
end
|
92
|
+
|
93
|
+
def load_existing_contentful_structure_file
|
94
|
+
JSON.parse(File.read(config.config['contentful_structure_dir']), symbolize_names: true).with_indifferent_access
|
95
|
+
end
|
96
|
+
|
97
|
+
def set_content_model_parameters
|
98
|
+
validate_content_model_files
|
99
|
+
@converted_model_dir = config.config['converted_model_dir']
|
100
|
+
@content_types = config.config['content_model_json']
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_content_model_files
|
104
|
+
fail ArgumentError, 'Set PATH for content model JSON file. View README' if config.config['content_model_json'].nil?
|
105
|
+
fail ArgumentError, 'Set PATH where converted content model file will be saved. View README' if config.config['converted_model_dir'].nil?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Contentful
|
2
|
+
module Exporter
|
3
|
+
module Drupal
|
4
|
+
class ContentType
|
5
|
+
|
6
|
+
attr_reader :exporter, :config, :type, :schema
|
7
|
+
|
8
|
+
def initialize(exporter, config, type, schema)
|
9
|
+
@exporter = exporter
|
10
|
+
@config = config
|
11
|
+
@type = type
|
12
|
+
@schema = schema
|
13
|
+
end
|
14
|
+
|
15
|
+
def save_content_types_as_json
|
16
|
+
exporter.create_directory("#{config.entries_dir}/#{type}")
|
17
|
+
config.db[:node].where(type: type).each do |content_row|
|
18
|
+
extract_data(content_row)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def extract_data(content_row)
|
25
|
+
puts "Saving #{type} - id: #{content_row[:nid]}"
|
26
|
+
db_object = map_fields(content_row)
|
27
|
+
exporter.write_json_to_file("#{config.entries_dir}/#{type}/#{db_object[:id]}.json", db_object)
|
28
|
+
end
|
29
|
+
|
30
|
+
def map_fields(row, result = {})
|
31
|
+
result.merge!(set_default_data(row))
|
32
|
+
result.merge!(find_related_data(row))
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def id(content_id)
|
37
|
+
"#{type}_#{content_id}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def author(user_id)
|
41
|
+
{type: 'Author', id: "user_#{user_id}"}
|
42
|
+
end
|
43
|
+
|
44
|
+
def tags(entity_row_id)
|
45
|
+
entity_tags(entity_row_id).each_with_object([]) do |tag, tags|
|
46
|
+
linked_tag = {type: 'EntryTag', id: "tag_#{tag[:field_tags_tid]}"}
|
47
|
+
tags << linked_tag
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def entity_tags(entity_id)
|
52
|
+
config.db[:field_data_field_tags].where(entity_id: entity_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_default_data(row, result = {})
|
56
|
+
result[:id] = id(row[:nid])
|
57
|
+
result[:title] = row[:title]
|
58
|
+
result[:author] = author(row[:uid])
|
59
|
+
result[:tags] = tags(row[:nid]) unless tags(row[:nid]).empty?
|
60
|
+
result[:created_at] = created_at(row[:created])
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_related_data(row, result = {})
|
65
|
+
schema.each do |key, column_name|
|
66
|
+
result[key] = column_name.is_a?(String) ? fetch_data_from_related_table(row[:nid], column_name) : fetch_custom_tags(row[:nid], column_name)
|
67
|
+
end
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def fetch_data_from_related_table(entity_id, table_name)
|
72
|
+
related_row = get_related_row(entity_id, table_name)
|
73
|
+
fetch_data_from_related_row(related_row, table_name)
|
74
|
+
end
|
75
|
+
|
76
|
+
def fetch_data_from_related_row(related_row, table_name)
|
77
|
+
respond_to_file?(related_row, table_name) ? get_file_id(related_row, table_name) : related_value(related_row, table_name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def respond_to_file?(related_row, table_name)
|
81
|
+
file_id = "#{table_name}_fid".to_sym
|
82
|
+
(related_row.present? && related_row.first[file_id]) ? true : false
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_file_id(related_row, table_name)
|
86
|
+
file_key = "#{table_name}_fid".to_sym
|
87
|
+
file_id = related_row.first[file_key]
|
88
|
+
file_asset_id = file_id(file_id)
|
89
|
+
link_asset_to_content_type(file_asset_id)
|
90
|
+
end
|
91
|
+
|
92
|
+
def file_id(file_id)
|
93
|
+
config.db[:file_managed].where(fid: file_id).first[:fid]
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_related_row(entity_id, table_name)
|
97
|
+
config.db[related_table_name(table_name)].where(entity_id: entity_id)
|
98
|
+
end
|
99
|
+
|
100
|
+
def link_asset_to_content_type(file_asset_id)
|
101
|
+
{type: 'File', id: "file_#{file_asset_id}"}
|
102
|
+
end
|
103
|
+
|
104
|
+
def related_value(related_rows, table_name)
|
105
|
+
value = related_rows.empty? ? nil : related_rows.first[field_name(table_name)]
|
106
|
+
convert_type_value(value, table_name)
|
107
|
+
end
|
108
|
+
|
109
|
+
def fetch_custom_tags(entity_id, table_name)
|
110
|
+
custom_tag_table = "field_data_#{table_name['table']}".to_sym
|
111
|
+
tag_id = "#{table_name['table']}_tid".to_sym
|
112
|
+
config.db[custom_tag_table].where(entity_id: entity_id).each_with_object([]) do |content_tag, tags|
|
113
|
+
lined_tags = {type: 'EntryTag', id: "tag_#{content_tag[tag_id]}"}
|
114
|
+
tags << lined_tags
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def related_table_name(table_name)
|
119
|
+
"field_data_#{table_name}".to_sym
|
120
|
+
end
|
121
|
+
|
122
|
+
def field_name(table_name)
|
123
|
+
"#{table_name}_value".to_sym
|
124
|
+
end
|
125
|
+
|
126
|
+
def created_at(timestamp)
|
127
|
+
Time.at(timestamp).to_datetime
|
128
|
+
end
|
129
|
+
|
130
|
+
def convert_type_value(value, column_name)
|
131
|
+
if value.is_a?(BigDecimal)
|
132
|
+
value.to_f
|
133
|
+
elsif boolean_column?(column_name)
|
134
|
+
convert_boolean_value(value)
|
135
|
+
else
|
136
|
+
value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def boolean_column?(column_name)
|
141
|
+
exporter.boolean_columns && exporter.boolean_columns.flatten.include?(column_name) ? true : false
|
142
|
+
end
|
143
|
+
|
144
|
+
def convert_boolean_value(value)
|
145
|
+
value.nil? ? nil : (value == 1 ? true : false)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|