radiant-import_export-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in radiant-import_export-extension.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Andrew vonderLuft
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ h1. Import Export
2
+
3
+ The *Import Export* extension supports an enhanced version of exporting your Radiant database, and
4
+ adds the ability to import the results of an export operation.
5
+
6
+ h2. Installation
7
+
8
+ Add this line to your application's Gemfile: @gem 'radiant-import_export-extension'@
9
+ And then execute: @$ bundle@
10
+ Or install it yourself as: @$ gem install radiant-import_export-extension@
11
+
12
+ h2. History
13
+
14
+ * 2014-04-07 - Gemify [Andrew vonderLuft]
15
+ * 2013-12-31 - added capability to import/export join tables [Andrew vonderLuft]
16
+ * since then - "tweaks and enhancements":https://github.com/radiant/radiant-import-export-extension/commits/master
17
+ * 2009-09-22 - Skip addition (ability to skip tables) [Johannes Fahrenkrug]
18
+ * 2007-04-18 - First release [Sean Cribbs]
19
+
20
+ h2. Usage
21
+
22
+ * Import: $ rake db:import [TEMPLATE=path/to/export.yml]
23
+ * Export: $ rake db:export [SKIP="tabelname1,tablename2"] [TEMPLATE=path/to/export.yml] (or browse to /admin/export )
24
+
25
+ h2. Contributing
26
+
27
+ # Fork it
28
+ # Create your feature branch (`git checkout -b my-new-feature`)
29
+ # Commit your changes (`git commit -am 'Add some feature'`)
30
+ # Push to the branch (`git push origin my-new-feature`)
31
+ # Create new Pull Request
32
+
33
+ h2. To do
34
+
35
+ * Import still not working with Oracle
36
+ * Add more tests
37
+
38
+ h2. "Contributors":https://github.com/radiant/radiant-import-export-extension/graphs/contributors
39
+
40
+ * "Sean Cribbs":https://github.com/seancribbs
41
+ * "Johannes Fahrenkrug":https://github.com/jfahrenkrug
42
+ * "Drew Neil":https://github.com/nelstrom
43
+ * "Istvan Hoka":https://github.com/ihoka
44
+ * "Chris Parrish":https://github.com/chrisparrish
45
+ * "Andrew vonderLuft":https://github.com/avonderluft
46
+ * "et al.":https://github.com/radiant/radiant-import-export-extension/graphs/contributors
47
+
@@ -0,0 +1,26 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'bundler/gem_tasks'
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the import_export extension.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the import_export extension.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'ImportExportExtension'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ # Load any custom rakefiles for extension
26
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,5 @@
1
+ class Admin::ExportController < ApplicationController
2
+ def yaml
3
+ render :text => Exporter.export, :content_type => "text/yaml"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ # Uncomment this if you reference any of your controllers in activate
2
+ # require_dependency 'application'
3
+
4
+ class ImportExportExtension < Radiant::Extension
5
+ version ImportExport::VERSION
6
+ description "Supports more flexible import and export to Radiant databases."
7
+ url "https://github.com/radiant/radiant-import-export-extension"
8
+
9
+ def activate
10
+ end
11
+
12
+ def deactivate
13
+ end
14
+
15
+ end
@@ -0,0 +1,25 @@
1
+ class Exporter
2
+ extend Loader
3
+ cattr_accessor :models, :join_tables
4
+ self.models = models_from_database
5
+ self.join_tables = join_tables_from_database
6
+
7
+ def self.export
8
+ hash = {'name' => 'Last export', 'description' => "Backup of the database as of #{Time.now.to_s(:rfc822)}"}
9
+ hash['records'] = {}
10
+ self.models.each do |klass|
11
+ recs = klass.find(:all)
12
+ if recs
13
+ hash['records'][klass.name.pluralize] = recs.inject({}) { |h, record| h[record.id.to_s] = record.attributes; h }
14
+ end
15
+ end
16
+ self.join_tables.each do |table|
17
+ recs = ActiveRecord::Base.connection.select_all("SELECT * FROM #{table}")
18
+ if recs
19
+ i = 0
20
+ hash['records'][table.camelize] = recs.inject({}) { |h, record| h[i += 1] = record; h }
21
+ end
22
+ end
23
+ hash.to_yaml
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module ImportExport
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,30 @@
1
+ module Loader
2
+ # In most cases singularizing a table's name yields the model's name but in
3
+ # special cases where the model's name is already seen as plural by rails, it
4
+ # expects the table's name to then also be plural (so the model: 'MyData' goes
5
+ # with the table: 'my_data')
6
+ def models_from_database
7
+ tables = ActiveRecord::Base.connection.tables
8
+ tables.delete "config"
9
+ if ENV['SKIP']
10
+ table_names = ENV['SKIP'].split(',')
11
+ table_names.each do |table_to_skip|
12
+ puts "Skipping #{table_to_skip}"
13
+ tables.delete table_to_skip.strip
14
+ end
15
+ end
16
+ models = tables.collect { |table| table.camelize.singularize.constantize rescue nil || table.camelize.constantize rescue nil }.compact
17
+ models << Radiant::Config
18
+ end
19
+
20
+ def join_tables_from_database
21
+ join_tables = []
22
+ excluded_tables = ["schema_migrations"]
23
+ ActiveRecord::Base.connection.tables.each do |table|
24
+ unless ActiveRecord::Base.connection.columns(table).map { |c| c.name }.include?("id")
25
+ join_tables << table unless excluded_tables.include?(table)
26
+ end
27
+ end
28
+ join_tables.compact
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ module Radiant
2
+ class Setup
3
+ def create_records(template)
4
+ records = template['records']
5
+ if records
6
+ puts
7
+ records.keys.each do |key|
8
+ table = key.underscore
9
+ # assume this is an ActiveRecord model if table has column 'id'
10
+ if key == "Radiant::Configs" || ActiveRecord::Base.connection.columns(table).map { |c| c.name }.include?("id")
11
+ feedback "Importing '#{key.to_s.underscore.humanize.titleize}' table data" do
12
+ model = model(key)
13
+ model.reset_column_information
14
+ record_pairs = order_by_id(records[key])
15
+ step do
16
+ record_pairs.each do |id, record|
17
+ begin
18
+ #puts "i: #{id}"
19
+ #puts "r: #{record}"
20
+ #puts
21
+ r = model.new(record)
22
+ r.id = id
23
+ r.save
24
+ # UserActionObserver sets user to null, so we have to update explicitly
25
+ model.update_all({:created_by_id => record['created_by_id']}, {:id => r.id}) if r.respond_to? :created_by_id
26
+ rescue Exception => e
27
+ puts "Failed to create record #{id}. Reason: #{e}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ else
33
+ feedback "Importing '#{key.to_s.underscore.humanize.titleize}' join table data" do
34
+ table = key.underscore
35
+ record_pairs = records[key].sort
36
+ step do
37
+ record_pairs.each do |id, record|
38
+ begin
39
+ sql = "INSERT INTO #{table} (#{record.keys.join(", ")}) VALUES (#{record.values.join(", ")})"
40
+ ActiveRecord::Base.connection.execute(sql)
41
+ rescue Exception => e
42
+ puts "Failed to create record #{id}. Reason: #{e}"
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,88 @@
1
+ namespace :db do
2
+ desc "Import a database template from db/export.yml. Specify the TEMPLATE environment variable to load a different template. This is not intended for new installations, but restoration from previous exports."
3
+ task :import do
4
+ require 'highline/import'
5
+ say "ERROR: Specify a template to load with the TEMPLATE environment variable." and exit unless (ENV['TEMPLATE'] and File.exists?(ENV['TEMPLATE']))
6
+ Rake::Task["db:schema:load"].invoke
7
+ # Use what Radiant::Setup for the heavy lifting
8
+ require 'radiant/setup'
9
+ require 'lib/radiant_setup_create_records_patch'
10
+ setup = Radiant::Setup.new
11
+
12
+ # Load the data from the export file
13
+ data = YAML.load_file(ENV['TEMPLATE'] || "#{RAILS_ROOT}/db/export.yml")
14
+
15
+ # Reorder Radiant::Config table to ensure ids are sequential with no gaps, to prevent load error
16
+ configs_in_order = data['records']['Radiant::Configs'].sort_by { |k,v| v['id'] }
17
+ new_configs = {}
18
+ configs_in_order.each do |attributes|
19
+ rec_id = configs_in_order.index(attributes) + 1
20
+ new_configs[rec_id.to_s] = {'id' => rec_id}
21
+ Radiant::Config.column_names.delete_if { |el| el == "id" }.each do |att|
22
+ new_configs[rec_id.to_s][att] = attributes[1][att]
23
+ end
24
+ end
25
+ data['records']['Radiant::Configs'].replace(new_configs)
26
+
27
+ # Load the users first so created_by fields can be updated
28
+ users_only = {'records' => {'Users' => data['records'].delete('Users')}}
29
+ passwords = []
30
+ users_only['records']['Users'].each do |id, attributes|
31
+ if attributes['password']
32
+ passwords << [attributes['id'], attributes['password'], attributes['salt']]
33
+ attributes['password'] = 'radiant'
34
+ attributes['password_confirmation'] = 'radiant'
35
+ end
36
+ end
37
+ setup.send :create_records, users_only
38
+
39
+ # Hack to get passwords transferred correctly.
40
+ passwords.each do |id, password, salt|
41
+ User.update_all({:password => password, :salt => salt}, ['id = ?', id])
42
+ end
43
+
44
+ # Now load the created users into the hash and load the rest of the data
45
+ data['records'].each do |klass, records|
46
+ records.each do |key, attributes|
47
+ if attributes.has_key? 'created_by'
48
+ attributes['created_by'] = User.find(attributes['created_by']) rescue nil
49
+ end
50
+ if attributes.has_key? 'updated_by'
51
+ attributes['updated_by'] = User.find(attributes['updated_by']) rescue nil
52
+ end
53
+ end
54
+ end
55
+ setup.send :create_records, data
56
+
57
+ # if env set, adjust the auto increment counter, needed for DB2
58
+ if ENV['FIXIDS']
59
+ puts
60
+ data['records'].each do |klass, records|
61
+ tabname = klass.to_s.singularize.constantize.table_name
62
+
63
+ if ActiveRecord::Base.connection and !ActiveRecord::Base.connection.schema.to_s.empty?
64
+ tabname = ActiveRecord::Base.connection.schema.to_s + '.' + tabname
65
+ end
66
+
67
+ res = ActiveRecord::Base.connection.select_value("SELECT max(id)+1 from #{tabname};")
68
+
69
+ if res
70
+ puts "Adjusting auto increment value for the id column of #{tabname}..."
71
+ ActiveRecord::Base.connection.execute("alter table #{tabname} alter column id restart with #{res};")
72
+ end
73
+ end
74
+ puts 'Done.'
75
+ end
76
+ end
77
+
78
+ desc "Export a database template to db/export_TIME.yml. Specify the TEMPLATE environment variable to use a different file."
79
+ task :export do
80
+ require "activerecord" if !defined?(ActiveRecord)
81
+ require "#{RAILS_ROOT}/config/environment.rb"
82
+ ActiveRecord::Base.establish_connection
83
+ require "#{File.expand_path(File.dirname(__FILE__) + '/../')}/loader.rb"
84
+ require "#{File.expand_path(File.dirname(__FILE__) + '/../')}/exporter.rb"
85
+ template_name = ENV['TEMPLATE'] || "#{RAILS_ROOT}/db/export_#{Time.now.utc.strftime("%Y%m%d%H%M%S")}.yml"
86
+ File.open(template_name, "w") {|f| f.write Exporter.export }
87
+ end
88
+ end
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'import_export/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "radiant-import_export-extension"
8
+ gem.version = ImportExport::VERSION
9
+ gem.authors = ["Sean Cribbs","Johannes Fahrenkrug","Drew Neil","Istvan Hoka","Chris Parrish","Andrew vonderLuft"]
10
+ gem.email = ["avonderluft@avlux.net"]
11
+ gem.description = %q{Enhanced version of exporting and importing your Radiant database tables to/from YAML files}
12
+ gem.summary = %q{Supports more flexible import and export to Radiant databases.}
13
+ gem.homepage = "https://github.com/radiant/radiant-import-export-extension"
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ImportExportExtensionTest < Test::Unit::TestCase
4
+
5
+ def test_initialization
6
+ assert_equal File.join(File.expand_path(RADIANT_ROOT), 'vendor', 'extensions', 'import_export'), ImportExportExtension.root
7
+ assert_equal 'Import Export', ImportExportExtension.extension_name
8
+ end
9
+
10
+ end
@@ -0,0 +1,18 @@
1
+ # Load the environment
2
+ unless defined? RADIANT_ROOT
3
+ ENV["RAILS_ENV"] = "test"
4
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
5
+ end
6
+ require "#{RADIANT_ROOT}/test/test_helper"
7
+
8
+ class Test::Unit::TestCase
9
+
10
+ # Include a helper to make testing Radius tags easier
11
+ test_helper :extension_tags
12
+
13
+ # Add the fixture directory to the fixture path
14
+ self.fixture_path << File.dirname(__FILE__) + "/fixtures"
15
+
16
+ # Add more helper methods to be used by all extension tests here...
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-import_export-extension
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Sean Cribbs
14
+ - Johannes Fahrenkrug
15
+ - Drew Neil
16
+ - Istvan Hoka
17
+ - Chris Parrish
18
+ - Andrew vonderLuft
19
+ autorequire:
20
+ bindir: bin
21
+ cert_chain: []
22
+
23
+ date: 2014-04-07 00:00:00 Z
24
+ dependencies: []
25
+
26
+ description: Enhanced version of exporting and importing your Radiant database tables to/from YAML files
27
+ email:
28
+ - avonderluft@avlux.net
29
+ executables: []
30
+
31
+ extensions: []
32
+
33
+ extra_rdoc_files: []
34
+
35
+ files:
36
+ - .gitignore
37
+ - Gemfile
38
+ - LICENSE.txt
39
+ - README.textile
40
+ - Rakefile
41
+ - app/controllers/admin/export_controller.rb
42
+ - import_export_extension.rb
43
+ - lib/exporter.rb
44
+ - lib/import_export/version.rb
45
+ - lib/loader.rb
46
+ - lib/radiant_setup_create_records_patch.rb
47
+ - lib/tasks/import_export_extension_tasks.rake
48
+ - radiant-import_export-extension.gemspec
49
+ - test/functional/import_export_extension_test.rb
50
+ - test/test_helper.rb
51
+ homepage: https://github.com/radiant/radiant-import-export-extension
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.25
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Supports more flexible import and export to Radiant databases.
84
+ test_files:
85
+ - test/functional/import_export_extension_test.rb
86
+ - test/test_helper.rb