drupal-exporter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|