mysql2_model 0.1.1

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