mysql2_model 0.1.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,167 @@
1
+ module Mysql2Model
2
+
3
+ # include this module in your class to inherit all of this awsomeness
4
+ # @example
5
+ # class MyClass
6
+ # include Mysql2Model::Container
7
+ # end
8
+ module Container
9
+
10
+ def self.included(base)
11
+ base.extend Forwardable
12
+ base.extend ClassMethods
13
+ base.extend Mysql2Model::Composer
14
+ #@TODO Do we need the delegators in the instance? ...not sure.
15
+ base.def_delegators :default_repository_config, :database, :username, :host, :password
16
+ base.class_eval do
17
+ class << self
18
+ extend Forwardable
19
+ def_delegators :default_repository_config, :database, :username, :host, :password
20
+ end
21
+ end
22
+ end
23
+
24
+ # @raise [ArgumentError] Row must be a Hash
25
+ # @param [Hash] row Expects a row from a Mysql2 resultset
26
+ def initialize(row)
27
+ raise ArgumentError, "must be a hash" unless row.is_a?(Hash)
28
+ @attributes = row
29
+ end
30
+
31
+ def default_repository_config # @private
32
+ self.class.default_repository_config
33
+ end
34
+
35
+ def respond_to?(method) # @private
36
+ return true if @attributes.key?(method)
37
+ super
38
+ end
39
+
40
+ # Delegate the id to the attribute :id insted of the Object_id
41
+ def id
42
+ @attributes[:id]
43
+ end
44
+
45
+ # Provide dynamic accessors to the internal attributes only
46
+ def method_missing(method, *args, &block)
47
+ if @attributes.key?(method)
48
+ @attributes[method]
49
+ else
50
+ super
51
+ end
52
+ end
53
+
54
+ #member notation convenience method
55
+ def [](method)
56
+ @attributes[method]
57
+ end
58
+ #member notation convenience method
59
+ def []=(method,value)
60
+ @attributes[method] = value
61
+ end
62
+
63
+ #datamapper style resource convenience method
64
+ def attribute_get(method)
65
+ @attributes[method]
66
+ end
67
+
68
+ #datamapper style resource convenience method
69
+ def attribute_set(method,value)
70
+ @attributes[method]=value
71
+ end
72
+
73
+ module ClassMethods
74
+
75
+ def default_repository_config # @private
76
+ OpenStruct.new(Mysql2Model::Client.repositories[default_repository_name][:config])
77
+ end
78
+
79
+ # Define which repository or repositories act as the destination(s) of your model.
80
+ # @example Single Repository
81
+ # class MyClass
82
+ # include Mysql2Model::Container
83
+ # self.default_repository_name
84
+ # :infrastructure
85
+ # end
86
+ # end
87
+ # @example Multiple Repositories
88
+ # class MyClass
89
+ # include Mysql2Model::Container
90
+ # self.default_repository_name
91
+ # [:db1,:db2,:db3]
92
+ # end
93
+ # end
94
+ # @todo Should probably rename this to just default_repository since Array != Symbol or just "repository"; "default_repository_name" came from Datamapper
95
+ # @abstract
96
+ def default_repository_name
97
+ :default
98
+ end
99
+
100
+ # Your models repository client via the cache
101
+ def client
102
+ Mysql2Model::Client[default_repository_name]
103
+ end
104
+
105
+ # @param [String] statement Uncomposed MySQL Statement
106
+ # @param [Array] args arguements for composure
107
+ # @yieldparam [String] composed_sql Composed MySQL Statement
108
+ # @yieldreturn the return of the block
109
+ def with_composed_sql(statement='',*args)
110
+ composed_sql = compose_sql(statement,*args).strip
111
+ log.info("SQL:[#{composed_sql}]")
112
+ yield composed_sql
113
+ end
114
+
115
+ # @return the sum of adding the first value from each of the rows
116
+ # primarily useful with count queries running against multiple repos
117
+ # @todo considering renaming value_sum => value, value => value_for_each, but what happens if value is a String instead of Numeric?
118
+ # @todo Remove the block pattern, we will need to utilize the block for the evented query pattern
119
+ def value_sum(statement='',*args)
120
+ statement = yield if block_given?
121
+ with_composed_sql(statement,*args) do |sql|
122
+ client.query(sql).inject(0) { |sum,row|
123
+ sum += row.first.last
124
+ }
125
+ end
126
+ end
127
+
128
+ # Useful with queries that only return one result, like a COUNT.
129
+ # @return [Object] only the first value from the row when there is only one row
130
+ # @return [Array] that contains the first value from each row if multiple rows are returned; as in a COUNT against multiple repos
131
+ # @todo Remove the block pattern, we will need to utilize the block for the evented query pattern
132
+ def value(statement='',*args)
133
+ statement = yield if block_given?
134
+ with_composed_sql(statement,*args) do |composed_sql|
135
+ if (rv = client.query(composed_sql)).count > 1
136
+ rv.map {|row| row.first.last }
137
+ else
138
+ rv.first.first.last
139
+ end
140
+ end
141
+ end
142
+
143
+ # Flavor the behavior by returning the resultset as instances of self instead of Mysql2::Result
144
+ def query(statement='',*args)
145
+ statement = yield if block_given?
146
+ with_composed_sql(statement,*args) do |composed_sql|
147
+ response = client.query(composed_sql)
148
+ if response.respond_to?(:map)
149
+ response.map do |row|
150
+ # @todo Patch Mysql2 to support loading the primitives directly into custom class :as => CustomClass, and remove this map
151
+ # @todo This is defeating Mysql2's lazy loading, but it's good for proof-of-concept
152
+ self.new(row)
153
+ end
154
+ else
155
+ response
156
+ end
157
+ end
158
+ end
159
+ alias_method :execute, :query #allow the user to choose whether they want the mysql2 DSL or activerecord DSL
160
+
161
+ def log # @private
162
+ Mysql2Model::LOGGER
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'active_support/core_ext/object/blank'
3
+ require 'active_support/core_ext/time'
4
+ require 'active_support/core_ext/date_time'
5
+ require 'mysql2'
6
+ require 'forwardable'
7
+ require 'logging'
8
+
9
+ module Mysql2Model
10
+ VERSION = File.read(File.expand_path(File.dirname(__FILE__) + '/../VERSION')).strip
11
+ LOGGER = Logging.logger(STDOUT)
12
+ LOGGER.level = :info
13
+ end
14
+
15
+ require 'mysql2_model/config'
16
+ require 'mysql2_model/client'
17
+ require 'mysql2_model/container'
18
+ require 'mysql2_model/composer'
@@ -0,0 +1,88 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mysql2_model}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["donnoman"]
12
+ s.date = %q{2010-09-03}
13
+ s.description = %q{Provides a class suitable to be used as a model, that includes connection management, variable interpolation, object coercion and helper methods to support using direct MySQL statements for database interaction.}
14
+ s.email = %q{donnoman@donovanbray.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".gitignore",
21
+ ".yardopts",
22
+ "CHANGELOG.md",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "MIT-LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "examples/mtdb.rb",
30
+ "examples/repositories.yml",
31
+ "examples/subscriber.rb",
32
+ "lib/mysql2_model.rb",
33
+ "lib/mysql2_model/client.rb",
34
+ "lib/mysql2_model/composer.rb",
35
+ "lib/mysql2_model/config.rb",
36
+ "lib/mysql2_model/container.rb",
37
+ "mysql2_model.gemspec",
38
+ "spec/mysql2_model/client_spec.rb",
39
+ "spec/mysql2_model/composer_spec.rb",
40
+ "spec/mysql2_model/config_spec.rb",
41
+ "spec/mysql2_model/container_spec.rb",
42
+ "spec/mysql2_model_spec.rb",
43
+ "spec/repositories.yml.fixture",
44
+ "spec/spec.opts",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/donnoman/mysql2_model}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.7}
51
+ s.summary = %q{Mysql2Model provides a container for creating model code based on MySQL Statements utilizing the Mysql2 client}
52
+ s.test_files = [
53
+ "spec/mysql2_model/client_spec.rb",
54
+ "spec/mysql2_model/container_spec.rb",
55
+ "spec/mysql2_model/config_spec.rb",
56
+ "spec/mysql2_model/composer_spec.rb",
57
+ "spec/mysql2_model_spec.rb",
58
+ "spec/spec_helper.rb",
59
+ "examples/mtdb.rb",
60
+ "examples/subscriber.rb"
61
+ ]
62
+
63
+ if s.respond_to? :specification_version then
64
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
65
+ s.specification_version = 3
66
+
67
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
+ s.add_runtime_dependency(%q<mysql2>, ["~> 0.2"])
69
+ s.add_runtime_dependency(%q<activesupport>, ["~> 2.3"])
70
+ s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
71
+ s.add_runtime_dependency(%q<logging>, ["~> 1"])
72
+ s.add_development_dependency(%q<rspec>, ["~> 1.3"])
73
+ else
74
+ s.add_dependency(%q<mysql2>, ["~> 0.2"])
75
+ s.add_dependency(%q<activesupport>, ["~> 2.3"])
76
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
77
+ s.add_dependency(%q<logging>, ["~> 1"])
78
+ s.add_dependency(%q<rspec>, ["~> 1.3"])
79
+ end
80
+ else
81
+ s.add_dependency(%q<mysql2>, ["~> 0.2"])
82
+ s.add_dependency(%q<activesupport>, ["~> 2.3"])
83
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
84
+ s.add_dependency(%q<logging>, ["~> 1"])
85
+ s.add_dependency(%q<rspec>, ["~> 1.3"])
86
+ end
87
+ end
88
+
@@ -0,0 +1,84 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Mysql2Model::Client do
4
+ describe "repositories" do
5
+ it "should have repositories" do
6
+ Mysql2Model::Client.repositories[:default].should_not be_nil
7
+ end
8
+ end
9
+ describe "getting repositories" do
10
+ it "should have a :default repository that is a 'Mysql2::Client'" do
11
+ Mysql2Model::Client[:default].class.name.should eql("Mysql2::Client")
12
+ end
13
+ end
14
+ describe "setting repositories" do
15
+ it "should add the :mtdb1 repository" do
16
+ Mysql2Model::Client[:mtdb1] = YAML.load(File.read(File.expand_path(File.dirname(__FILE__) + '/../repositories.yml')))[:repositories][:default]
17
+ Mysql2Model::Client[:mtdb1].class.name.should eql("Mysql2::Client")
18
+ end
19
+ end
20
+ describe "load_repos" do
21
+ context "forced" do
22
+ it "should load_repos subsequent times" do
23
+ rv = YAML.load(File.new(Mysql2Model::Config.repository_path, 'r'))
24
+ YAML.should_receive(:load).twice.and_return(rv)
25
+ 2.times do
26
+ Mysql2Model::Client.load_repos(true)
27
+ end
28
+ end
29
+ end
30
+ context "not forced" do
31
+ it "should not load_repos again" do
32
+ YAML.should_not_receive(:load)
33
+ Mysql2Model::Client.load_repos
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ class M2MClient
40
+ include Mysql2Model::Container
41
+ def self.all
42
+ query("SELECT * FROM mysql2_model_test")
43
+ end
44
+ end
45
+
46
+ describe M2MClient do
47
+ describe "default_repository_name" do
48
+ before :each do
49
+ Mysql2Model::Config.should_receive(:repository_path).any_number_of_times.and_return(File.expand_path(File.dirname(__FILE__) + '/../repositories.yml'))
50
+ Mysql2Model::Client.load_repos(true)
51
+ end
52
+ describe "with multiple repositories" do
53
+ before :each do
54
+ Mysql2Model::Client[:default2] = YAML.load(File.read(File.expand_path(File.dirname(__FILE__) + '/../repositories.yml')))[:repositories][:default]
55
+ Mysql2Model::Client[:default3] = YAML.load(File.read(File.expand_path(File.dirname(__FILE__) + '/../repositories.yml')))[:repositories][:default]
56
+ M2MClient.stub!(:default_repository_name).and_return([:default,:default2,:default3])
57
+ end
58
+ it "should return single resultset of merged rows" do
59
+ M2MClient.all.size.should eql(6)
60
+ end
61
+ it "should add the values returned" do
62
+ M2MClient.value_sum("SELECT COUNT(*) from mysql2_model_test").should eql(6)
63
+ end
64
+ it "should return an array of values" do
65
+ M2MClient.value("SELECT COUNT(*) from mysql2_model_test").should eql([2,2,2])
66
+ end
67
+ end
68
+ describe "with single repository" do
69
+ before :each do
70
+ M2MClient.stub!(:default_repository_name).and_return(:default)
71
+ end
72
+ it "should return single resultset" do
73
+ M2MClient.all.size.should eql(2)
74
+ end
75
+ it "should add the values returned" do
76
+ M2MClient.value_sum("SELECT COUNT(*) from mysql2_model_test").should eql(2)
77
+ end
78
+ it "should return the value" do
79
+ M2MClient.value("SELECT COUNT(*) from mysql2_model_test").should eql(2)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,123 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class M2MComposer
4
+ include Mysql2Model::Container
5
+ end
6
+
7
+ describe M2MComposer do
8
+ describe "compose_sql" do
9
+ context "string" do
10
+ it "should return the string" do
11
+ M2MComposer.compose_sql("one two three 4").should eql("one two three 4")
12
+ end
13
+ end
14
+ context "array" do
15
+ it "should assemble use multiple arguments as the array" do
16
+ M2MComposer.compose_sql("%s %s %s %d",'one','two','three',4).should eql("one two three 4")
17
+ end
18
+ it "should support passing in an array" do
19
+ M2MComposer.compose_sql(["one two three 4",'one','two','three',4]).should eql("one two three 4")
20
+ end
21
+ it "should support passing in an array and single string" do
22
+ #or should this raise?
23
+ M2MComposer.compose_sql(["one two three 4"]).should eql("one two three 4")
24
+ end
25
+ it "should support printf style substitution" do
26
+ M2MComposer.compose_sql("%s %s %s %d",'one','two','three',4).should eql("one two three 4")
27
+ end
28
+ it "should support ? placeholders" do
29
+ M2MComposer.compose_sql("? ? ? ?",'one','two','three',4).should eql("one two three 4")
30
+ end
31
+ it "should support named bind variables" do
32
+ M2MComposer.compose_sql(":uno :dos :tres :cuatro :uno :dos :tres :cuatro",:uno => 'one', :dos => 'two',:tres => 'three', :cuatro => 4).should eql("one two three 4 one two three 4")
33
+ end
34
+ it "should raise an error with mismatched number of replacements" do
35
+ lambda { M2MComposer.compose_sql("? ? ? ?",'one','two','three') }.should raise_error(Mysql2Model::PreparedStatementInvalid)
36
+ end
37
+ end
38
+ end
39
+ describe M2MComposer do
40
+
41
+ before :each do
42
+ @client = Mysql2Model::Client[:default]
43
+ end
44
+
45
+ describe "query" do
46
+ it "should be composed with a string" do
47
+ @client.should_receive(:query).with("SELECT 1").and_return([])
48
+ M2MComposer.query("SELECT 1")
49
+ end
50
+ it "should be composed with multiple arguments" do
51
+ @client.should_receive(:query).with("one two three 4").and_return([])
52
+ M2MComposer.query("%s %s %s %d",'one','two','three',4)
53
+ end
54
+ it "should be composed with an array" do
55
+ @client.should_receive(:query).with("one two three 4").and_return([])
56
+ M2MComposer.query(["%s %s %s %d",'one','two','three',4])
57
+ end
58
+ context "with a block" do
59
+ it "should be composed when in an array" do
60
+ @client.should_receive(:query).with("one two three 4").and_return([])
61
+ M2MComposer.query do
62
+ ["%s %s %s %d",'one','two','three',4]
63
+ end
64
+ end
65
+ it "should be composed when a string" do
66
+ @client.should_receive(:query).with("one two three 4").and_return([])
67
+ M2MComposer.query do
68
+ "one two three 4"
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ describe "value" do
76
+ it "should be composed with a string" do
77
+ @client.should_receive(:query).with("SELECT 1").and_return([])
78
+ M2MComposer.query("SELECT 1")
79
+ end
80
+ it "should be composed with multiple arguments" do
81
+ @client.should_receive(:query).with("one two three 4").and_return([])
82
+ M2MComposer.query("%s %s %s %d",'one','two','three',4)
83
+ end
84
+ it "should be composed with an array" do
85
+ @client.should_receive(:query).with("one two three 4").and_return([])
86
+ M2MComposer.query(["%s %s %s %d",'one','two','three',4])
87
+ end
88
+ context "with a block" do
89
+ it "should be composed when in an array" do
90
+ @client.should_receive(:query).with("one two three 4").and_return([])
91
+ M2MComposer.query do
92
+ ["%s %s %s %d",'one','two','three',4]
93
+ end
94
+ end
95
+ it "should be composed when a string" do
96
+ @client.should_receive(:query).with("one two three 4").and_return([])
97
+ M2MComposer.query do
98
+ "one two three 4"
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "convert" do
105
+ context "time" do
106
+ it "should convert a time" do
107
+ M2MComposer.convert(Time.utc(2000,1,2,20,15,1)).should eql("2000-01-02 20:15:01")
108
+ end
109
+ it "should convert a date" do
110
+ M2MComposer.convert(Date.new(2000,1,2)).should eql("2000-01-02")
111
+ end
112
+ it "should convert a datetime" do
113
+ M2MComposer.convert(DateTime.new(2000,1,2,20,15,1)).should eql("2000-01-02 20:15:01")
114
+ end
115
+ it "should convert a time via query" do
116
+ M2MComposer.query("UPDATE mysql2_model_test SET created_at = '?' WHERE id = 1",Time.utc(2000,1,2,20,15,1))
117
+ M2MComposer.value("SELECT created_at FROM mysql2_model_test WHERE id = 1").should eql(Time.utc(2000,1,2,20,15,1))
118
+ end
119
+ end
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Mysql2Model::Config do
4
+ describe "repository_path" do
5
+ it "should be muteable" do
6
+ Mysql2Model::Config.repository_path = 'databases.yml'
7
+ Mysql2Model::Config.repository_path.should eql('databases.yml')
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class M2MContainer
4
+ include Mysql2Model::Container
5
+
6
+ def self.default_repository_array
7
+ [database,username,password,host]
8
+ end
9
+
10
+ def default_repository_array
11
+ [database,username,password,host]
12
+ end
13
+ end
14
+
15
+ describe M2MContainer do
16
+ before :each do
17
+ Mysql2Model::Config.should_receive(:repository_path).any_number_of_times.and_return(File.expand_path(File.dirname(__FILE__) + '/../repositories.yml.fixture'))
18
+ Mysql2Model::Client.load_repos(true)
19
+ end
20
+ describe "class" do
21
+ it "should have direct access to the default_repository hash members" do
22
+ M2MContainer.default_repository_array.should eql(['mysql2_model_test','root','gibberish','localhost'])
23
+ end
24
+ end
25
+ describe "instance" do
26
+ it "should have direct access to the default_repository hash members" do
27
+ M2MContainer.new({}).default_repository_array.should eql(['mysql2_model_test','root','gibberish','localhost'])
28
+ end
29
+ end
30
+ end
31
+
32
+ describe M2MContainer, "mysql2 methods" do
33
+ before :each do
34
+ Mysql2Model::Config.should_receive(:repository_path).any_number_of_times.and_return(File.expand_path(File.dirname(__FILE__) + '/../repositories.yml'))
35
+ Mysql2Model::Client.load_repos(true) #fooling with the class repository path, need to make sure we don't use the fixture
36
+ end
37
+ describe "query" do
38
+ it "should return an array with a member named 'test'" do
39
+ M2MContainer.query("SELECT * FROM mysql2_model_test").first.name.should eql('test')
40
+ end
41
+ end
42
+
43
+ describe "value" do
44
+ it "should return only the first value of the first row" do
45
+ M2MContainer.value("SELECT COUNT(*) FROM mysql2_model_test").should eql(2)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Mysql2Model" do
4
+ it "should report the same version as in the VERSION file" do
5
+ Mysql2Model::VERSION.to_s.should == IO.read(File.expand_path(File.dirname(__FILE__) + "/../VERSION")).strip
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ :repositories:
2
+ :default:
3
+ :database: mysql2_model_test
4
+ :username: root
5
+ :password: gibberish
6
+ :host: localhost
7
+ :secondary:
8
+ :database: mysql2_model_test
9
+ :username: root
10
+ :password: gibberish
11
+ :host: localhost
12
+ :m1:
13
+ :database: mysql2_model_test
14
+ :username: root
15
+ :password: gibberish
16
+ :host: localhost
17
+ :m2:
18
+ :database: mysql2_model_test
19
+ :username: root
20
+ :password: gibberish
21
+ :host: localhost
22
+ :m3:
23
+ :database: mysql2_model_test
24
+ :username: root
25
+ :password: gibberish
26
+ :host: localhost
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format specdoc
3
+ --loadby mtime
4
+ --reverse
5
+ --backtrace
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'mysql2_model'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'ruby-debug'
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.before(:all) do
10
+ Mysql2Model::Config.repository_path = File.join(File.dirname(__FILE__), 'repositories.yml')
11
+ Mysql2Model::LOGGER.level = :fatal
12
+ client = Mysql2::Client.new(YAML.load(File.read(Mysql2Model::Config.repository_path))[:repositories][:default])
13
+ client.query %[ DROP TABLE IF EXISTS mysql2_model_test ]
14
+ client.query %[
15
+ CREATE TABLE IF NOT EXISTS mysql2_model_test (
16
+ id MEDIUMINT NOT NULL AUTO_INCREMENT,
17
+ name VARCHAR(40),
18
+ value VARCHAR(40),
19
+ created_at DATETIME,
20
+ updated_at DATETIME,
21
+ PRIMARY KEY (id)
22
+ )
23
+ ]
24
+ client.query %[
25
+ INSERT INTO mysql2_model_test (
26
+ name, value, updated_at, created_at
27
+ )
28
+
29
+ VALUES (
30
+ 'test', 'garbage', NOW(), NOW()
31
+ )
32
+ ]
33
+ client.query %[
34
+ INSERT INTO mysql2_model_test (
35
+ name, value, updated_at, created_at
36
+ )
37
+
38
+ VALUES (
39
+ 'test2', 'garbage2', NOW(), NOW()
40
+ )
41
+ ]
42
+ end
43
+ end