hasten 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDI0OWQyMjE1ODRhNGJhNWNmY2Y3YmJjMzk3OTU1NzYxMmYxYWNmZQ==
5
+ data.tar.gz: !binary |-
6
+ OGU2NDQ3Yjg1NDE4NTYzZmM2NDI1MjVjMDU0Mjg0ZTAxMzlmZTRhYg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YmI2Njc3MDJlYTcyYTE3NDBhYzMzM2JkNjU4ODUxMmRiMmIzYTRjYWEzMDJi
10
+ Yjg1MDIzNjAyZmY4ZmRkM2I4ZDkyYzgyNzJiYzQ4ZmM2Mjg2MGQ2YTI3YjJj
11
+ ZjYxNjg3MWZiZTc0NTE1NDA0MmFiNjJlZTM5NDI5NGM4ZDRhNzM=
12
+ data.tar.gz: !binary |-
13
+ NzIyZTg2ZjJhNmM5OTg2MTM1OGI0NjZkYmU4ZTc5ODVmNjM1ZDY4MjZjYmI5
14
+ ZDRjNTIzNmM4MzBiOWIwNzQyYjY2OTIxMzY2ZjA5Mzk1NmI4OGVmZWYyMWVh
15
+ ZDJlYmY2NzA0OWYxMWRmYWU0YTI3Mjk3ZGY2YzQ4NzhiODVkNDY=
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Derrick Parkhurst
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,40 @@
1
+ Hasten
2
+ ===============
3
+ [![Gem Version](https://badge.fury.io/rb/hasten.svg)](http://badge.fury.io/rb/hasten)
4
+ [![Build Status](https://travis-ci.org/thirtysixthspan/hasten.svg?branch=master)](https://travis-ci.org/thirtysixthspan/hasten)
5
+
6
+ Overview
7
+ --------
8
+
9
+ Hasten speeds up the import of mysql dumps containing very large innodb tables with multiple indexes by setting certain mysql modes, removing all indexes from table definitions, and then altering the tables to add the indexes back once all inserts have been completed.
10
+
11
+ USAGE
12
+ -----
13
+ This gem provides an executable script `hasten` that can be used as follows to import SQL files exported from mysqldump.
14
+ ```
15
+ cat DUMPFILE | hasten | mysql -uUSER -pPASSWORD DATABASE
16
+ ```
17
+
18
+ License
19
+ -------
20
+ Copyright (c) 2015
21
+ Derrick Parkhurst (derrick.parkhurst@gmail.com),
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ of this software and associated documentation files (the "Software"), to deal
25
+ in the Software without restriction, including without limitation the rights
26
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ copies of the Software, and to permit persons to whom the Software is
28
+ furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in
31
+ all copies or substantial portions of the Software.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39
+ THE SOFTWARE.
40
+
@@ -0,0 +1,18 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ namespace :gem do
9
+
10
+ task :build do
11
+ `gem build jiragit.gemspec`
12
+ end
13
+
14
+ task :install => [:build] do
15
+ `gem install pkg/jiragit*.gem`
16
+ end
17
+
18
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # Hasten (speed up) the import of mysql dumps containing very large
3
+ # innodb tables with multiple indexes.
4
+ #
5
+ # Sets modes
6
+ # Indexes are removed from all table definitions.
7
+ # Indexes are added after all inserts are complete.
8
+ #
9
+ # usage:
10
+ # cat DUMPFILE | hasten | mysql -uroot DATABASE
11
+ #
12
+ require 'hasten'
13
+
14
+
15
+ Hasten::DEFAULT_MODES.each { |mode| puts mode }
16
+ Hasten::Dump.new(STDIN, STDOUT).execute
17
+ puts Hasten::COMMIT
@@ -0,0 +1,9 @@
1
+ require "hasten/version"
2
+ require "hasten/modes"
3
+ require "hasten/command"
4
+ require "hasten/commands/table"
5
+ require "hasten/commands/view"
6
+ require "hasten/commands/insert"
7
+ require "hasten/commands/other"
8
+ require "hasten/commands/classes"
9
+ require "hasten/dump"
@@ -0,0 +1,50 @@
1
+ module Hasten
2
+
3
+ class Command < Array
4
+
5
+ def complete?
6
+ last.match(/;$/) ||
7
+ last.match(/^--/) ||
8
+ last.match(/^\s*$/)
9
+ end
10
+
11
+ def <<(items)
12
+ if items.respond_to? :each
13
+ items.each { |item| self.push item }
14
+ else
15
+ self.push items
16
+ end
17
+ end
18
+
19
+ def type
20
+ COMMAND_CLASSES
21
+ .detect { |klass| klass.match?(sql) }
22
+ .to_s
23
+ .gsub(/^.*::/,'')
24
+ end
25
+
26
+ def sql
27
+ conditional ? extract : strip
28
+ end
29
+
30
+ private
31
+
32
+ def squish
33
+ self.map(&:chomp).join(' ')
34
+ end
35
+
36
+ def strip
37
+ squish.gsub(/^\s+/,'').gsub(/;\s+$/,'')
38
+ end
39
+
40
+ def conditional
41
+ squish.match(/^\s*\/\*\![0-9]{5}\s+(.*?)\s*\*\//)
42
+ end
43
+
44
+ def extract
45
+ conditional[1]
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,10 @@
1
+ module Hasten
2
+
3
+ COMMAND_CLASSES = [
4
+ Table,
5
+ View,
6
+ Insert,
7
+ Other
8
+ ]
9
+
10
+ end
@@ -0,0 +1,11 @@
1
+ module Hasten
2
+
3
+ class Insert < Command
4
+
5
+ def self.match?(sql)
6
+ sql.match(/^INSERT/)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Hasten
2
+
3
+ class Other < Command
4
+
5
+ def self.match?(sql)
6
+ sql.match(/.*/i)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,45 @@
1
+ module Hasten
2
+
3
+ class Table < Command
4
+
5
+ def self.match?(sql)
6
+ sql.match(/^CREATE\s+(TEMPORARY\s+)*TABLE/i)
7
+ end
8
+
9
+ def name
10
+ sql[/(?<=`).*?(?=`)/]
11
+ end
12
+
13
+ def without_indexes
14
+ revised = reject &index_line
15
+ revised[-2].gsub!(/,$/,'')
16
+ revised
17
+ end
18
+
19
+ def indexes
20
+ self
21
+ .select(&index_line)
22
+ .map{ |line| line.gsub(/^\s+/,'') }
23
+ .map{ |line| line.gsub(/,\s*$/,'') }
24
+ .map{ |line| line.chomp }
25
+ end
26
+
27
+ def index_statements
28
+ indexes
29
+ .map { |definition| "ALTER TABLE `#{name}` ADD #{definition};" }
30
+ end
31
+
32
+ private
33
+
34
+ def index_line
35
+ ->(line){
36
+ line.match(/^\s*(KEY|INDEX)/i) ||
37
+ line.match(/^\s*(FULLTEXT|SPATIAL)\s+(KEY|INDEX)/i) ||
38
+ line.match(/^\s*(UNIQUE|FOREIGN)\s+(KEY|INDEX)/i) ||
39
+ line.match(/^\s*CONSTRAINT.*?(UNIQUE|FOREIGN)\s+(KEY|INDEX)/i)
40
+ }
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,16 @@
1
+ module Hasten
2
+
3
+ class View < Command
4
+
5
+ def self.match?(sql)
6
+ sql.match(/^(CREATE|REPLACE).*?VIEW\s+(.*?)\s+AS/i) ||
7
+ sql.match(/^VIEW\s+(.*?)\s+AS/i)
8
+ end
9
+
10
+ def name
11
+ sql.match(/VIEW\s+`*(.*?)`.*?AS/i)[1]
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,82 @@
1
+ module Hasten
2
+
3
+ class Dump
4
+
5
+ attr_accessor :command
6
+
7
+ def initialize(io_in, io_out)
8
+ @io_in = io_in
9
+ @io_out = io_out
10
+ end
11
+
12
+ def execute
13
+ while self.command = parse_command
14
+ dump_command
15
+ end
16
+ dump_indexes
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :io_in, :io_out
22
+
23
+ def tables
24
+ @tables ||= []
25
+ end
26
+
27
+ def views
28
+ @views ||= []
29
+ end
30
+
31
+ def parse_command
32
+ return unless line = io_in.gets
33
+
34
+ self.command = Command.new
35
+ self.command << line
36
+ return command if command.complete?
37
+
38
+ while line = io_in.gets
39
+ self.command << line
40
+ break if command.complete?
41
+ end
42
+
43
+ command
44
+ end
45
+
46
+ def dump_command
47
+ send("dump_#{command.type.to_s.downcase}")
48
+ end
49
+
50
+ def dump_table
51
+ tables << table = Table.new
52
+ table << command
53
+ io_out.puts table.without_indexes
54
+ end
55
+
56
+ def dump_view
57
+ views << view = View.new
58
+ view << command
59
+ io_out.puts view
60
+ end
61
+
62
+ def dump_insert
63
+ io_out.puts command
64
+ end
65
+
66
+ def dump_other
67
+ io_out.puts command
68
+ end
69
+
70
+ def dump_indexes
71
+ tables_not_overwritten_by_views.each do |table|
72
+ io_out.puts table.index_statements
73
+ end
74
+ end
75
+
76
+ def tables_not_overwritten_by_views
77
+ tables.reject { |table| views.map(&:name).include?(table.name) }
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,70 @@
1
+ module Hasten
2
+
3
+ # By default, MySQL runs with autocommit mode enabled. This means that
4
+ # as soon as you execute a statement that updates (modifies) a table,
5
+ # MySQL stores the update on disk to make it permanent.
6
+ #
7
+ # To disable autocommit mode explicitly, use the following statement:
8
+ # SET autocommit=0;
9
+ # After disabling autocommit mode by setting the autocommit variable
10
+ # to zero, changes to transaction-safe tables (such as those for
11
+ # InnoDB, BDB, or NDBCLUSTER) are not made permanent immediately.
12
+ # You must use COMMIT to store your changes to disk or ROLLBACK to
13
+ # ignore the changes.
14
+ #
15
+ # From http://dev.mysql.com/doc/refman/5.0/en/commit.html
16
+ #
17
+ DISABLE_AUTOCOMMIT = "SET SESSION autocommit=0;"
18
+ COMMIT = "COMMIT;"
19
+
20
+ # If you have UNIQUE constraints on secondary keys, you can speed
21
+ # up a table import by turning off the uniqueness checks temporarily
22
+ # during the import operation:
23
+ # SET unique_checks=0;
24
+ # ... import operation ...
25
+ # SET unique_checks=1;
26
+ # For big tables, this saves a lot of disk I/O because InnoDB can then
27
+ # use its insert buffer to write secondary index records as a batch.
28
+ # Be certain that the data contains no duplicate keys.
29
+ #
30
+ # From http://dev.mysql.com/doc/refman/5.0/en/converting-tables-to-innodb.html
31
+ #
32
+ DISABLE_UNIQUENESS_CHECKS = "SET SESSION unique_checks=0;"
33
+
34
+ # To make it easier to reload dump files for tables that have foreign
35
+ # key relationships, mysqldump automatically includes a statement in
36
+ # the dump output to set foreign_key_checks to 0. This avoids problems
37
+ # with tables having to be reloaded in a particular order when the dump
38
+ # is reloaded. It is also possible to set this variable manually:
39
+ # mysql> SET foreign_key_checks = 0;
40
+ # mysql> SOURCE dump_file_name;
41
+ # mysql> SET foreign_key_checks = 1;
42
+ # This enables you to import the tables in any order if the dump file
43
+ # contains tables that are not correctly ordered for foreign keys. It
44
+ # also speeds up the import operation.
45
+ #
46
+ # From http://dev.mysql.com/doc/refman/5.1/en/create-table-foreign-keys.html
47
+ #
48
+ DISABLE_FOREIGN_KEY_CHECKS = "SET SESSION foreign_key_checks=0;"
49
+
50
+ # The sql_log_bin variable controls whether logging to the binary log
51
+ # is done. The default value is 1 (do logging). To change logging for
52
+ # the current session, change the session value of this variable. The
53
+ # session user must have the SUPER privilege to set this variable. Set
54
+ # this variable to 0 for a session to temporarily disable binary
55
+ # logging while making changes to the master which you do not want to
56
+ # replicate to the slave.
57
+ # SET sql_log_bin = {0|1}
58
+ #
59
+ # From http://dev.mysql.com/doc/refman/5.7/en/set-sql-log-bin.html
60
+ #
61
+ DISABLE_BINARY_LOGS = "SET SESSION sql_log_bin=0;"
62
+
63
+ DEFAULT_MODES = [
64
+ DISABLE_AUTOCOMMIT,
65
+ DISABLE_UNIQUENESS_CHECKS,
66
+ DISABLE_FOREIGN_KEY_CHECKS,
67
+ DISABLE_BINARY_LOGS
68
+ ]
69
+
70
+ end
@@ -0,0 +1,3 @@
1
+ module Hasten
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,80 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Hasten::Command do
4
+
5
+ it "strips whitespace from sql" do
6
+ subject << " SET TIME_ZONE='+00:00'; "
7
+ expect(subject.sql).to eq "SET TIME_ZONE='+00:00'"
8
+ end
9
+
10
+ it "extracts conditional sql" do
11
+ subject << "/*!40103 SET TIME_ZONE='+00:00' */;"
12
+ expect(subject.sql).to eq "SET TIME_ZONE='+00:00'"
13
+ end
14
+
15
+ it "considers comments complete" do
16
+ subject << "-- Server version 5.6.22"
17
+ expect(subject.complete?).to be_true
18
+ end
19
+
20
+ it "considers semicolon terminated lines complete" do
21
+ subject << "DROP TABLE IF EXISTS `test`;"
22
+ expect(subject.complete?).to be_true
23
+ end
24
+
25
+ it "considers lines without semicolons incomplete" do
26
+ subject << "DROP TABLE IF EXISTS `test`"
27
+ expect(subject.complete?).to be_false
28
+ end
29
+
30
+ it "parses multiline sql" do
31
+ subject << <<-EOC
32
+ SELECT *
33
+ FROM `test`
34
+ WHERE c1 = 'name';
35
+ EOC
36
+ expect(subject.complete?).to be_true
37
+ end
38
+
39
+ it "identifies Table definitions" do
40
+ subject << <<-EOC
41
+ CREATE TABLE `test` (
42
+ `id` int(11) NOT NULL AUTO_INCREMENT,
43
+ `q1` int(11) DEFAULT NULL,
44
+ `q2` int(11) DEFAULT NULL,
45
+ PRIMARY KEY (`id`),
46
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
47
+ EOC
48
+ expect(subject.type).to eq('Table')
49
+ end
50
+
51
+ it "identifies View definitions" do
52
+ subject << <<-EOC
53
+ CREATE VIEW `test` AS
54
+ SELECT * FROM `section1`
55
+ UNION
56
+ SELECT * FROM `section2`;
57
+ EOC
58
+ expect(subject.type).to eq('View')
59
+ end
60
+
61
+ it "identifies Insert statements" do
62
+ subject << <<-EOC
63
+ INSERT INTO `contact_fields` VALUES
64
+ (1,'Name',0),
65
+ (2,'Address',0),
66
+ (3,'Phone',0);
67
+ EOC
68
+ expect(subject.type).to eq('Insert')
69
+ end
70
+
71
+ it "accepts other commands" do
72
+ command1 = Hasten::Command.new
73
+ command1 << "line 1"
74
+ command1 << "line 2"
75
+ command2 = Hasten::Command.new
76
+ command2 << command1
77
+ expect(command2.sql).to eq command1.sql
78
+ end
79
+
80
+ end
@@ -0,0 +1,101 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Hasten::Dump do
4
+
5
+ context "with indexed tables" do
6
+
7
+ let(:in_io) {
8
+ StringIO.new(<<-EOS)
9
+ CREATE TABLE `test` (
10
+ `id` int(11) NOT NULL AUTO_INCREMENT,
11
+ `q1` int(11) DEFAULT NULL,
12
+ `q2` int(11) DEFAULT NULL,
13
+ PRIMARY KEY (`id`),
14
+ KEY `q1_idx` (`q1`),
15
+ KEY `q1_q2_idx` (`q1`,`q2`)
16
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
17
+ EOS
18
+ }
19
+
20
+ let(:out_io) { StringIO.new }
21
+
22
+ before do
23
+ described_class.new(in_io,out_io).execute
24
+ end
25
+
26
+ it "shifts indexes to the end of the dump" do
27
+ expect(out_io.string).to include "ALTER TABLE `test` ADD KEY `q1_idx` (`q1`);"
28
+ end
29
+
30
+ it "removes indexes from the table definition" do
31
+ expect(squish out_io.string).to include (squish <<-EOS)
32
+ CREATE TABLE `test` (
33
+ `id` int(11) NOT NULL AUTO_INCREMENT,
34
+ `q1` int(11) DEFAULT NULL,
35
+ `q2` int(11) DEFAULT NULL,
36
+ PRIMARY KEY (`id`)
37
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
38
+ EOS
39
+ end
40
+
41
+ end
42
+
43
+ context "with insert statements" do
44
+
45
+ let(:in_io) {
46
+ StringIO.new(<<-EOS)
47
+ CREATE TABLE `test` (
48
+ `id` int(11) NOT NULL AUTO_INCREMENT,
49
+ `q1` int(11) DEFAULT NULL,
50
+ `q2` int(11) DEFAULT NULL,
51
+ PRIMARY KEY (`id`)
52
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
53
+ INSERT INTO `test` VALUES
54
+ (1,1,2),
55
+ (2,3,4),
56
+ (3,5,6);
57
+ EOS
58
+ }
59
+
60
+ let(:out_io) { StringIO.new }
61
+
62
+ before do
63
+ described_class.new(in_io,out_io).execute
64
+ end
65
+
66
+ it "passes insert statement unmodified" do
67
+ expect(squish out_io.string).to include (squish <<-EOS)
68
+ INSERT INTO `test` VALUES
69
+ (1,1,2),
70
+ (2,3,4),
71
+ (3,5,6);
72
+ EOS
73
+ end
74
+
75
+ end
76
+
77
+ context "with views" do
78
+
79
+ let(:in_io) {
80
+ StringIO.new(<<-EOS)
81
+ VIEW `test` AS
82
+ SELECT `section1`.`q1`,`section2`.`q2`
83
+ FROM `test`
84
+ JOIN `section1s` ON `test`.`section1_id` = `section1s`.`id`
85
+ JOIN `section2s` ON `test`.`section2_id` = `section2s`.`id`
86
+ EOS
87
+ }
88
+
89
+ let(:out_io) { StringIO.new }
90
+
91
+ before do
92
+ described_class.new(in_io,out_io).execute
93
+ end
94
+
95
+ it "passes insert statement unmodified" do
96
+ expect(squish out_io.string).to include (squish in_io.string)
97
+ end
98
+
99
+ end
100
+
101
+ end
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require './lib/hasten'
3
+
4
+ def squish(s)
5
+ s.gsub(/[\s\n]/,'')
6
+ end
@@ -0,0 +1,32 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Hasten::Table do
4
+
5
+ it "identifies delimited table names" do
6
+ subject << <<-EOC
7
+ CREATE TABLE `test` (
8
+ `id` int(11) NOT NULL AUTO_INCREMENT,
9
+ `q1` int(11) DEFAULT NULL,
10
+ `q2` int(11) DEFAULT NULL,
11
+ PRIMARY KEY (`id`),
12
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
13
+ EOC
14
+ expect(subject.name).to eq('test')
15
+ end
16
+
17
+ it "identifies indexes" do
18
+ subject << [
19
+ "CREATE TABLE `test` (",
20
+ " `id` int(11) NOT NULL AUTO_INCREMENT,",
21
+ " `q1` int(11) DEFAULT NULL,",
22
+ " `q2` int(11) DEFAULT NULL,",
23
+ " PRIMARY KEY (`id`),",
24
+ " KEY `q1_idx` (`q1`),",
25
+ " KEY `q1_q2_idx` (`q1`,`q2`)",
26
+ ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"
27
+ ]
28
+ expect(subject.indexes.first).to eq "KEY `q1_idx` (`q1`)"
29
+ expect(subject.indexes.last).to eq "KEY `q1_q2_idx` (`q1`,`q2`)"
30
+ end
31
+
32
+ end
@@ -0,0 +1,26 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Hasten::View do
4
+
5
+ it "identifies delimited view names" do
6
+ subject << <<-EOC
7
+ CREATE VIEW `test` AS
8
+ SELECT * FROM `section1`
9
+ UNION
10
+ SELECT * FROM `section2`;
11
+ EOC
12
+ expect(subject.name).to eq('test')
13
+ end
14
+
15
+ it "identifies delimited view names for alternative syntax" do
16
+ subject << <<-EOC
17
+ VIEW `test` AS
18
+ SELECT `section1`.`q1`,`section2`.`q2`
19
+ FROM `test`
20
+ JOIN `section1s` ON `test`.`section1_id` = `section1s`.`id`
21
+ JOIN `section2s` ON `test`.`section2_id` = `section2s`.`id`
22
+ EOC
23
+ expect(subject.name).to eq('test')
24
+ end
25
+
26
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hasten
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Derrick Parkhurst
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Hasten the import of mysql dumps, especially those containing very large
42
+ innodb tables with multiple indexes.
43
+ email:
44
+ - derrick.parkhurst@gmail.com
45
+ executables:
46
+ - hasten
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - bin/hasten
54
+ - lib/hasten.rb
55
+ - lib/hasten/command.rb
56
+ - lib/hasten/commands/classes.rb
57
+ - lib/hasten/commands/insert.rb
58
+ - lib/hasten/commands/other.rb
59
+ - lib/hasten/commands/table.rb
60
+ - lib/hasten/commands/view.rb
61
+ - lib/hasten/dump.rb
62
+ - lib/hasten/modes.rb
63
+ - lib/hasten/version.rb
64
+ - spec/command_spec.rb
65
+ - spec/dump_spec.rb
66
+ - spec/spec_helper.rb
67
+ - spec/table_spec.rb
68
+ - spec/view_spec.rb
69
+ homepage: http://github.com/thirtysixthspan/hasten
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.4.5
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Hasten the import of mysqldumps dumps
93
+ test_files:
94
+ - spec/command_spec.rb
95
+ - spec/dump_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/table_spec.rb
98
+ - spec/view_spec.rb