sql_tasks 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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sql_tasks.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Within3
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,4 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ load 'lib/sql_tasks/tasks/sql_tasks.rake'
@@ -0,0 +1,9 @@
1
+ module SqlTasks
2
+
3
+ def self.install_tasks
4
+ load File.join(File.dirname(__FILE__), 'sql_tasks/tasks/sql_tasks.rake')
5
+ end
6
+
7
+ require 'sql_tasks/railtie' if defined?(Rails)
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ module SqlTasks
2
+ class Railtie < ::Rails::Railtie
3
+
4
+ rake_tasks do
5
+ load 'sql_tasks/tasks/sql_tasks.rake'
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,129 @@
1
+ require 'tempfile'
2
+ require 'shellwords'
3
+
4
+ class ShellCommand
5
+
6
+ def initialize(command, *args)
7
+ @arguments = args
8
+ @command = command
9
+ end
10
+
11
+ def to_s
12
+ command_string = @command
13
+ command_string << " " + arguments if arguments?
14
+ command_string
15
+ end
16
+
17
+ def arguments
18
+ @arguments.map do |options|
19
+ if Hash === options
20
+ if options[:password] == nil
21
+ options[:password] = ''
22
+ end
23
+ options.map do |args|
24
+ key, value = args.first, escaped(args.last)
25
+ "--%s=%s" % [key, value]
26
+ end
27
+ else
28
+ options
29
+ end
30
+ end.join(" ")
31
+ end
32
+
33
+ def execute
34
+ `#{to_s}`
35
+ end
36
+
37
+ def arguments?
38
+ @arguments.any?
39
+ end
40
+
41
+ private
42
+
43
+ def escaped(val)
44
+ Shellwords.shellescape(val)
45
+ end
46
+
47
+ end
48
+
49
+ class SqlCommand
50
+
51
+ def initialize(path, database_config)
52
+ @config = database_config
53
+ @path = path
54
+ end
55
+
56
+ def dump_data
57
+ command = ShellCommand.new("mysqldump", config_hash, "--skip-dump-date --skip-comments", @config["database"], { :tab => @path })
58
+ end
59
+
60
+ def load_data
61
+ ShellCommand.new("mysqlimport", config_hash, @config["database"], @path)
62
+ end
63
+
64
+ def import_schema
65
+ ShellCommand.new("mysql", config_hash, @config["database"], "<#{@path}")
66
+ end
67
+
68
+ def truncate_data
69
+ file = write_truncate_script
70
+ if @config["password"] == nil
71
+ ShellCommand.new(file.path, @config["username"], 'nopwd', escaped(@config["database"]))
72
+ else
73
+ ShellCommand.new(file.path, @config["username"], escaped(@config["password"]), escaped(@config["database"]))
74
+ end
75
+ end
76
+
77
+ def drop_db
78
+ ShellCommand.new("mysql", config_hash, '--execute="drop database %s;"' % @config["database"])
79
+ end
80
+
81
+ def create_db
82
+ ShellCommand.new("mysql", config_hash, '--execute="create database %s;"' % @config["database"])
83
+ end
84
+
85
+ private
86
+
87
+ def config_hash
88
+ { "user" => @config["username"], :password => @config["password"], :host => @config["host"] }
89
+ end
90
+
91
+ def escaped(val)
92
+ Shellwords.shellescape(val)
93
+ end
94
+
95
+ def write_truncate_script
96
+ script = <<-EOS
97
+ #!/usr/bin/env bash
98
+
99
+ user=$1
100
+ PASS=$2
101
+ dbname=$3
102
+ if [ "$PASS" == "nopwd" ]; then
103
+ basecmd="mysql --user=${user} ${dbname}"
104
+ else
105
+ basecmd="mysql --user=${user} --password=$PASS ${dbname}"
106
+ fi
107
+
108
+ tables=$(${basecmd} -e "SHOW TABLES;" | grep -v "+--" | grep -v "Tables_in_${dbname}")
109
+ if [ $? -ne 0 ]; then
110
+ echo "Unable to retrieve the table names." >&2
111
+ exit 1
112
+ fi
113
+
114
+ cmd=""
115
+
116
+ for table in ${tables}; do
117
+ cmd="${cmd} TRUNCATE ${table};"
118
+ done
119
+
120
+ $(${basecmd} -e "${cmd}")
121
+ EOS
122
+ Tempfile.new("mysqltruncate").tap do |file|
123
+ file.write(script)
124
+ file.rewind
125
+ file.chmod(0777)
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,66 @@
1
+ require File.dirname(__FILE__) + "/../sql_command"
2
+ require 'yaml'
3
+
4
+ namespace :sql do
5
+
6
+ task :prereqs do
7
+ @rails_env = ENV['RAILS_ENV'] || 'development'
8
+ @root = Dir.pwd
9
+ @config = YAML.load_file("#{@root}/config/database.yml")
10
+ @pathname = File.join(@root, "db", "#{@rails_env}_sql")
11
+ end
12
+
13
+ desc "Dump SQL data and schema to files"
14
+ task :dump => :prereqs do
15
+ command = SqlCommand.new(@pathname, @config[@rails_env])
16
+ command.dump_data.execute
17
+
18
+ end
19
+
20
+ task :load => :prereqs do
21
+
22
+ command = SqlCommand.new(File.join(@pathname, "*.txt"), @config[@rails_env])
23
+ command.load_data.execute
24
+
25
+ end
26
+
27
+ desc "Truncates all tables in config/database.yml"
28
+ task :truncate => :prereqs do
29
+
30
+ command = SqlCommand.new("", @config[@rails_env])
31
+ command.truncate_data.execute
32
+
33
+ end
34
+
35
+ task :refresh => [:truncate, :load]
36
+
37
+ namespace :db do
38
+
39
+ task :drop => :prereqs do
40
+
41
+ command = SqlCommand.new("", @config[@rails_env])
42
+ command.drop_db.execute
43
+
44
+ end
45
+
46
+ task :create => :prereqs do
47
+
48
+ command = SqlCommand.new("", @config[@rails_env])
49
+ command.create_db.execute
50
+ end
51
+
52
+ task :setup => [:drop, :create, "sql:schema:load", "sql:load"]
53
+
54
+ end
55
+
56
+ namespace :schema do
57
+
58
+ task :load => :prereqs do
59
+ Dir[File.join(@pathname, "*.sql")].each do |sql|
60
+ SqlCommand.new(sql, @config[@rails_env]).import_schema.execute
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,3 @@
1
+ module SqlTasks
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,163 @@
1
+ require 'shellwords'
2
+ require 'sql_tasks/sql_command'
3
+
4
+ describe ShellCommand do
5
+
6
+ it "takes the command" do
7
+ ShellCommand.new("mysqlimport").tap do |output|
8
+ output.should have_command("mysqlimport")
9
+ end
10
+ end
11
+
12
+ it "converts user to arguments" do
13
+ ShellCommand.new("mysqlimport", :user => "root").tap do |output|
14
+ output.should have_command "mysqlimport"
15
+ output.should have_parameter "--user=root"
16
+ end
17
+ end
18
+
19
+ it "converts user and password to arguments" do
20
+ ShellCommand.new("mysqlimport", :user => "root", :password => "blah").tap do |output|
21
+ output.should have_command "mysqlimport"
22
+ output.should have_parameter "--user=root"
23
+ output.should have_parameter "--password=blah"
24
+ end
25
+ end
26
+
27
+ it "does not have the password as a parameter when it's an empty string" do
28
+ ShellCommand.new("mysqlimport", :user => "root", :password => nil).tap do |output|
29
+ output.should have_command "mysqlimport"
30
+ output.should have_parameter "--user=root"
31
+ output.should have_parameter "--password="
32
+ end
33
+ end
34
+
35
+ it "takes single word arguments" do
36
+ ShellCommand.new("mysqlimport", "database_name").tap do |output|
37
+ output.should have_command "mysqlimport"
38
+ output.should have_parameter "database_name"
39
+ end
40
+ end
41
+
42
+ it "takes two single words arguments" do
43
+ ShellCommand.new("mysqlimport", "database_name", "file_path").tap do |output|
44
+ output.should have_command "mysqlimport"
45
+ output.should have_parameter "database_name"
46
+ output.should have_parameter "file_path"
47
+ end
48
+ end
49
+
50
+ it "takes a single word argument with the user argument" do
51
+ ShellCommand.new("mysqlimport", { :user => "root" }, "database_name").tap do |output|
52
+ output.should have_command "mysqlimport"
53
+ output.should have_parameter "--user=root"
54
+ output.should have_parameter "database_name"
55
+ end
56
+ end
57
+
58
+ it "executes a given command" do
59
+ command = ShellCommand.new("command")
60
+ command.should_receive(:`).with("command")
61
+ command.execute
62
+ end
63
+
64
+ describe SqlCommand do
65
+
66
+ it "executes a mysqldump command" do
67
+ config = {"username" => 'root', "password" => 'blah', "host" => 'hostname', "database" => 'database'}
68
+
69
+ SqlCommand.new("path", config).dump_data.tap do |output|
70
+ output.should have_command "mysqldump"
71
+ output.should have_parameter "--user=root"
72
+ output.should have_parameter "--password=blah"
73
+ output.should have_parameter "--host=hostname"
74
+ output.should have_parameter "--tab=path"
75
+ output.should have_parameter "database"
76
+ end
77
+
78
+ end
79
+
80
+ it "executes a mysqlimport command" do
81
+ config = {"username" => 'root', "password" => 'blah', "host" => 'hostname', "database" => 'database'}
82
+
83
+ SqlCommand.new("path", config).load_data.tap do |output|
84
+ output.should have_command "mysqlimport"
85
+ output.should have_parameter "database"
86
+ output.should have_parameter "path"
87
+ end
88
+ end
89
+
90
+ it "sets up the schema" do
91
+ config = {"username" => 'root', "password" => 'blah', "host" => 'hostname', "database" => 'database'}
92
+
93
+ SqlCommand.new("test.sql", config).import_schema.tap do |output|
94
+ output.should have_command "mysql"
95
+ output.should have_parameter "database"
96
+ output.should have_parameter "<test.sql"
97
+ end
98
+ end
99
+
100
+ it "executes truncate data command" do
101
+ config = {"username" => 'root', "password" => 'blah', "host" => 'hostname', "database" => 'database'}
102
+
103
+ SqlCommand.new("", config).truncate_data.tap do |output|
104
+ output.should have_command "mysqltruncate"
105
+ output.should have_parameter "database"
106
+ end
107
+ end
108
+
109
+ it "creates the truncate data command without the password" do
110
+ config = {"username" => 'root', "password" => nil, "host" => 'hostname', "database" => 'database'}
111
+
112
+ SqlCommand.new("", config).truncate_data.tap do |output|
113
+ output.should have_command "mysqltruncate"
114
+ output.should have_parameter "root"
115
+ output.should have_parameter "nopwd"
116
+ output.should have_parameter "database"
117
+ output.should_not have_parameter "hostname"
118
+ end
119
+ end
120
+
121
+ it "executes drop database command" do
122
+ config = {"username" => 'root', "password" => 'blah', "host" => 'hostname', "database" => 'database'}
123
+
124
+ SqlCommand.new("", config).drop_db.tap do |output|
125
+ output.should have_command "mysql"
126
+ output.should have_parameter '--execute=drop database database;'
127
+ end
128
+ end
129
+
130
+ it "executes create database command" do
131
+ config = {"username" => 'root', "password" => 'blah', "host" => 'hostname', "database" => 'database'}
132
+
133
+ SqlCommand.new("", config).create_db.tap do |output|
134
+ output.should have_command "mysql"
135
+ output.should have_parameter '--execute=create database database;'
136
+ end
137
+ end
138
+
139
+ it "escapes values" do
140
+ config = {"username" => 'root', "password" => 'pa$$word1', "host" => 'hostname', "database" => 'database'}
141
+
142
+ SqlCommand.new("", config).create_db.tap do |output|
143
+ output.to_s.should =~ %r{pa\\\$\\\$word1}
144
+ end
145
+ end
146
+
147
+ end
148
+
149
+ RSpec::Matchers.define :have_command do |expected|
150
+ match do |actual|
151
+ parts = actual.to_s.split(" ")
152
+ File.basename(parts.first) =~ /^#{expected}/
153
+ end
154
+ end
155
+
156
+ RSpec::Matchers.define :have_parameter do |expected|
157
+ match do |actual|
158
+ parts = Shellwords.shellsplit(actual.to_s)
159
+ parts.include?(expected)
160
+ end
161
+ end
162
+
163
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sql_tasks/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sql_tasks"
7
+ s.version = SqlTasks::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Joe Fiorini", "Attila Domokos"]
10
+ s.email = ["joe@joefiorini.com", "adomokos@within3.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Faster loading and dumping for your MySQL database fixtures.}
13
+ s.description = %q{Uses built-in mysql commands for dumping/loading of plain text fixtures and schema.}
14
+
15
+ s.rubyforge_project = "sql_tasks"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+
23
+ s.add_development_dependency "rspec"
24
+
25
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sql_tasks
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Joe Fiorini
14
+ - Attila Domokos
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-03-11 00:00:00 -05:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: rspec
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ type: :development
35
+ version_requirements: *id001
36
+ description: Uses built-in mysql commands for dumping/loading of plain text fixtures and schema.
37
+ email:
38
+ - joe@joefiorini.com
39
+ - adomokos@within3.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - .gitignore
48
+ - Gemfile
49
+ - LICENSE
50
+ - Rakefile
51
+ - lib/sql_tasks.rb
52
+ - lib/sql_tasks/railtie.rb
53
+ - lib/sql_tasks/sql_command.rb
54
+ - lib/sql_tasks/tasks/sql_tasks.rake
55
+ - lib/sql_tasks/version.rb
56
+ - spec/sql_command_spec.rb
57
+ - sql_tasks.gemspec
58
+ has_rdoc: true
59
+ homepage: ""
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project: sql_tasks
88
+ rubygems_version: 1.5.0
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Faster loading and dumping for your MySQL database fixtures.
92
+ test_files:
93
+ - spec/sql_command_spec.rb