rmap 0.1.0
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.
- data/.gitignore +4 -0
- data/Gemfile +10 -0
- data/README.markdown +124 -0
- data/Rakefile +1 -0
- data/bin/rmap +18 -0
- data/lib/rmap/database.rb +61 -0
- data/lib/rmap/row.rb +44 -0
- data/lib/rmap/table.rb +328 -0
- data/lib/rmap/version.rb +3 -0
- data/lib/rmap.rb +10 -0
- data/rmap.gemspec +23 -0
- metadata +57 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
# Rmap - a simple yet powerfull object relational mapper
|
3
|
+
|
4
|
+
##Installation
|
5
|
+
|
6
|
+
```
|
7
|
+
gem install rmap
|
8
|
+
```
|
9
|
+
or add the following to your gem file:
|
10
|
+
|
11
|
+
```
|
12
|
+
gem 'rmap'
|
13
|
+
```
|
14
|
+
and then run bundle install from your shell.
|
15
|
+
|
16
|
+
##Basic configuration
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require 'rmap'
|
20
|
+
|
21
|
+
db = Rmap::Database.new :database => 'rmap', :username => 'root'
|
22
|
+
```
|
23
|
+
You can get more configuration options by going to the mysql2 gem documentation, as rmap wraps the mysql2 gem and simply passes through the conf hash to it:
|
24
|
+
|
25
|
+
* https://github.com/brianmario/mysql2
|
26
|
+
|
27
|
+
For instance a more advanced configuration might be:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'rmap'
|
31
|
+
|
32
|
+
db = Rmap::Database.new :database => 'rmap', :host => 'localhost', :username => 'root', :password => "secret"
|
33
|
+
```
|
34
|
+
|
35
|
+
## How to use
|
36
|
+
|
37
|
+
The following will return a representation of the 'posts' table:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
db.posts
|
41
|
+
```
|
42
|
+
### Creating
|
43
|
+
|
44
|
+
You can insert rows into the posts table by doing the following:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
db.posts.insert(:title => "Hello World", :body => "This is a test")
|
48
|
+
```
|
49
|
+
|
50
|
+
### Retrieval
|
51
|
+
|
52
|
+
You can list all the posts by doing the following:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
db.posts.all.each do |post|
|
56
|
+
puts "title #{post.title}"
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
You can list all the posts that contain the word apple by doing the following:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
db.posts.contains(:body, "apple").all.each do |post|
|
64
|
+
puts "title #{post.title}"
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
You can list all the posts that contain the word apple or pear by doing the following:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
db.posts.contains(:body, ["apple", "pear"]).all.each do |post|
|
72
|
+
puts "title #{post.title}"
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
You can retrieve a particular post (row) by doing the following:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
db.posts.eq(:id, 7).first
|
80
|
+
```
|
81
|
+
|
82
|
+
and then you can print the title to the screen:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
puts db.posts.eq(:id, 7).first.title
|
86
|
+
```
|
87
|
+
|
88
|
+
### Joins
|
89
|
+
|
90
|
+
Joins are really easy. To retrieve all the posts by gmail users, you can do the following:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
db.users.contains(:email, "@gmail.com").posts.all
|
94
|
+
```
|
95
|
+
|
96
|
+
### Deleting
|
97
|
+
|
98
|
+
You can delete all the posts by gmail users by doing the following:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
db.users.contains(:email, "@gmail.com").posts.delete
|
102
|
+
```
|
103
|
+
|
104
|
+
### Updating
|
105
|
+
|
106
|
+
You can update all the posts by gmail users by doing the following:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
db.users.contains(:email, "@gmail.com").posts.update(:published => true, :last_published => Time.now)
|
110
|
+
```
|
111
|
+
|
112
|
+
or if you just want to update a column:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
db.users.contains(:email, "@gmail.com").posts.published = true
|
116
|
+
```
|
117
|
+
|
118
|
+
more coming soon....
|
119
|
+
|
120
|
+
## License
|
121
|
+
|
122
|
+
Rmap is released under the MIT license:
|
123
|
+
|
124
|
+
* http://www.opensource.org/licenses/MIT
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/rmap
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
require 'rmap'
|
3
|
+
require 'ripl'
|
4
|
+
require 'ripl/multi_line'
|
5
|
+
|
6
|
+
db = Rmap::Database.new
|
7
|
+
|
8
|
+
current = Dir::getwd
|
9
|
+
while current != '/'
|
10
|
+
if ::File.file? "#{current}/conf.rmap.rb"
|
11
|
+
db.run("#{current}/conf.rmap.rb")
|
12
|
+
break
|
13
|
+
end
|
14
|
+
current = ::File.expand_path('../', current)
|
15
|
+
end
|
16
|
+
|
17
|
+
Ripl.start :binding => db.bindings
|
18
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
module Rmap
|
3
|
+
class Database
|
4
|
+
|
5
|
+
def initialize(conf={:username => 'root'})
|
6
|
+
@conf = conf
|
7
|
+
end
|
8
|
+
|
9
|
+
def client
|
10
|
+
if @client.nil?
|
11
|
+
@client = Mysql2::Client.new(@conf)
|
12
|
+
end
|
13
|
+
@client
|
14
|
+
end
|
15
|
+
|
16
|
+
def host(host)
|
17
|
+
@conf[:host] = host
|
18
|
+
end
|
19
|
+
|
20
|
+
def username(username)
|
21
|
+
@conf[:username] = username
|
22
|
+
end
|
23
|
+
|
24
|
+
def database(database)
|
25
|
+
@conf[:database] = database
|
26
|
+
end
|
27
|
+
|
28
|
+
def bindings
|
29
|
+
binding
|
30
|
+
end
|
31
|
+
|
32
|
+
def run(file_path)
|
33
|
+
instance_eval(::File.open(file_path).read, file_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def table?(name)
|
37
|
+
table_names.include?(name.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing name, *args
|
41
|
+
if table_names.include? name.to_s
|
42
|
+
Table.new(self, name)
|
43
|
+
else
|
44
|
+
super(name, *args)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def create(name)
|
49
|
+
@table_names = nil
|
50
|
+
client.query("create table `#{name}`(id int unsigned not null auto_increment primary key)")
|
51
|
+
end
|
52
|
+
|
53
|
+
def table_names
|
54
|
+
if @table_names.nil?
|
55
|
+
@table_names = client.query("show tables", :as => :array).map{|a| a[0]}
|
56
|
+
end
|
57
|
+
@table_names
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
data/lib/rmap/row.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Rmap
|
5
|
+
class Row
|
6
|
+
|
7
|
+
attr_accessor :id
|
8
|
+
|
9
|
+
def initialize(database, table_name, id)
|
10
|
+
@database = database
|
11
|
+
@table_name = table_name
|
12
|
+
@id = id
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch(*args)
|
16
|
+
@database.client.query("select #{(args.map { |field| "`#{@database.client.escape(field.to_s)}`"}).join(', ')} from `#{@table_name}` where id = '#{id}'", :as => :array).first
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(hash)
|
20
|
+
@database.client.query("update `#{@table_name}` set #{(hash.map{|k,v| "`#{k}`='#{@database.client.escape(v)}'"}).join(', ')} where id = '#{id}'")
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete
|
24
|
+
@database.client.query("delete from `#{@table_name}` where id = '#{id}'")
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing name, *args
|
28
|
+
if @database.table? name
|
29
|
+
Table.new(@database, name).join(Table.new(@database, @table_name).eq(:id, @id), *args)
|
30
|
+
elsif name.match(/\A.*=\Z/) && @database.method_missing(@table_name).column?(name.to_s.sub(/=\Z/, ""))
|
31
|
+
update(name[/\A(.*)=\Z/, 1] => args[0])
|
32
|
+
elsif @database.method_missing(@table_name).column? name
|
33
|
+
fetch(name).first
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
@database.client.query("select * from `#{@table_name}` where id = '#{id}'", :as => :hash).first.to_json
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/lib/rmap/table.rb
ADDED
@@ -0,0 +1,328 @@
|
|
1
|
+
|
2
|
+
module Rmap
|
3
|
+
class Table
|
4
|
+
BINARY_FILTER_METHODS = {
|
5
|
+
'eq' => lambda {|left,right| "#{left} = #{right}"},
|
6
|
+
'ne' => lambda {|left,right| "#{left} != #{right}"},
|
7
|
+
'lt' => lambda {|left,right| "#{left} < #{right}"},
|
8
|
+
'gt' => lambda {|left,right| "#{left} > #{right}"},
|
9
|
+
'le' => lambda {|left,right| "#{left} <= #{right}"},
|
10
|
+
'ge' => lambda {|left,right| "#{left} >= #{right}"},
|
11
|
+
'contains' => lambda {|left,right| "#{left} like concat('%', #{right}, '%')"},
|
12
|
+
'begins_with' => lambda {|left,right| "#{left} like concat('%', #{right})"},
|
13
|
+
'ends_with' => lambda {|left,right| "#{left} like concat(#{right}, '%')"},
|
14
|
+
'year_eq' => lambda {|left,right| "year(#{left}) = #{right}"},
|
15
|
+
'year_ne' => lambda {|left,right| "year(#{left}) != #{right}"},
|
16
|
+
'year_lt' => lambda {|left,right| "year(#{left}) < #{right}"},
|
17
|
+
'year_gt' => lambda {|left,right| "year(#{left}) > #{right}"},
|
18
|
+
'year_le' => lambda {|left,right| "year(#{left}) <= #{right}"},
|
19
|
+
'year_ge' => lambda {|left,right| "year(#{left}) >= #{right}"},
|
20
|
+
'month_eq' => lambda {|left,right| "month(#{left}) = #{right}"},
|
21
|
+
'month_ne' => lambda {|left,right| "month(#{left}) != #{right}"},
|
22
|
+
'month_lt' => lambda {|left,right| "month(#{left}) < #{right}"},
|
23
|
+
'month_gt' => lambda {|left,right| "month(#{left}) > #{right}"},
|
24
|
+
'month_le' => lambda {|left,right| "month(#{left}) <= #{right}"},
|
25
|
+
'month_ge' => lambda {|left,right| "month(#{left}) >= #{right}"},
|
26
|
+
'day_eq' => lambda {|left,right| "day(#{left}) = #{right}"},
|
27
|
+
'day_ne' => lambda {|left,right| "day(#{left}) != #{right}"},
|
28
|
+
'day_lt' => lambda {|left,right| "day(#{left}) < #{right}"},
|
29
|
+
'day_gt' => lambda {|left,right| "day(#{left}) > #{right}"},
|
30
|
+
'day_le' => lambda {|left,right| "day(#{left}) <= #{right}"},
|
31
|
+
'day_ge' => lambda {|left,right| "day(#{left}) >= #{right}"},
|
32
|
+
'hour_eq' => lambda {|left,right| "hour(#{left}) = #{right}"},
|
33
|
+
'hour_ne' => lambda {|left,right| "hour(#{left}) != #{right}"},
|
34
|
+
'hour_lt' => lambda {|left,right| "hour(#{left}) < #{right}"},
|
35
|
+
'hour_gt' => lambda {|left,right| "hour(#{left}) > #{right}"},
|
36
|
+
'hour_le' => lambda {|left,right| "hour(#{left}) <= #{right}"},
|
37
|
+
'hour_ge' => lambda {|left,right| "hour(#{left}) >= #{right}"},
|
38
|
+
'minute_eq' => lambda {|left,right| "minute(#{left}) = #{right}"},
|
39
|
+
'minute_ne' => lambda {|left,right| "minute(#{left}) != #{right}"},
|
40
|
+
'minute_lt' => lambda {|left,right| "minute(#{left}) < #{right}"},
|
41
|
+
'minute_gt' => lambda {|left,right| "minute(#{left}) > #{right}"},
|
42
|
+
'minute_le' => lambda {|left,right| "minute(#{left}) <= #{right}"},
|
43
|
+
'minute_ge' => lambda {|left,right| "minute(#{left}) >= #{right}"},
|
44
|
+
'second_eq' => lambda {|left,right| "second(#{left}) = #{right}"},
|
45
|
+
'second_ne' => lambda {|left,right| "second(#{left}) != #{right}"},
|
46
|
+
'second_lt' => lambda {|left,right| "second(#{left}) < #{right}"},
|
47
|
+
'second_gt' => lambda {|left,right| "second(#{left}) > #{right}"},
|
48
|
+
'second_le' => lambda {|left,right| "second(#{left}) <= #{right}"},
|
49
|
+
'second_ge' => lambda {|left,right| "second(#{left}) >= #{right}"},
|
50
|
+
}
|
51
|
+
|
52
|
+
attr_accessor :name
|
53
|
+
|
54
|
+
def initialize(database, name)
|
55
|
+
@database = database
|
56
|
+
@name = name
|
57
|
+
@binary_filter_methods_args = {}
|
58
|
+
Table::BINARY_FILTER_METHODS.each {|name, block| @binary_filter_methods_args[name] = []}
|
59
|
+
@join_list = []
|
60
|
+
@order_by_list = []
|
61
|
+
end
|
62
|
+
|
63
|
+
Table::BINARY_FILTER_METHODS.each do |name,block|
|
64
|
+
define_method name do |left, right|
|
65
|
+
@binary_filter_methods_args[name].push([left,right])
|
66
|
+
self
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def join(table, options = {})
|
71
|
+
@join_list.push({:table => table, :options => options});
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def order_by(sql_exression, desc = false)
|
76
|
+
@order_by_list.push([sql_exression, desc])
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
def column?(name)
|
81
|
+
@database.client.query("describe #{@name} `#{name}`").count > 0
|
82
|
+
end
|
83
|
+
|
84
|
+
def method_missing name, *args
|
85
|
+
if @database.table? name
|
86
|
+
Table.new(@database, name).join(self, *args)
|
87
|
+
elsif column? name
|
88
|
+
all.map{|row| row.fetch(name).first}
|
89
|
+
elsif column?(name.to_s.sub(/=\Z/, "")) && name.match(/\A(.*)=\Z/)
|
90
|
+
all.each{|row| row.update($1 => args[0])}
|
91
|
+
else
|
92
|
+
super
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def format_sql(sql)
|
97
|
+
out_buffer = []
|
98
|
+
sql = sql.to_s
|
99
|
+
while sql.length > 0
|
100
|
+
if sql.match(/\A(\s+|\d+\.\d+|\d+|\w+\()(.*)/)
|
101
|
+
out_buffer.push($1)
|
102
|
+
sql = $2
|
103
|
+
elsif sql.match(/\A(\w+)\.(\w+)(.*)/)
|
104
|
+
out_buffer.push("`#{$1}`.`#{$2}`")
|
105
|
+
sql = $3
|
106
|
+
elsif sql.match(/\A(\w+)(.*)/)
|
107
|
+
out_buffer.push("`#{@name}`.`#{$1}`")
|
108
|
+
sql = $2
|
109
|
+
else
|
110
|
+
sql.match(/\A(.)(.*)/)
|
111
|
+
out_buffer.push($1)
|
112
|
+
sql = $2
|
113
|
+
end
|
114
|
+
end
|
115
|
+
out_buffer.join
|
116
|
+
end
|
117
|
+
|
118
|
+
def quote(data)
|
119
|
+
"'" + @database.client.escape(data.to_s) + "'"
|
120
|
+
end
|
121
|
+
|
122
|
+
def generate_filter_conditions_sql
|
123
|
+
and_sql = []
|
124
|
+
Table::BINARY_FILTER_METHODS.each do |name, block|
|
125
|
+
@binary_filter_methods_args[name].each do |args|
|
126
|
+
or_sql = []
|
127
|
+
if args[0].class.name == 'Array'
|
128
|
+
args[0].each do |left|
|
129
|
+
or_sql.push(block.call(format_sql(left.to_s), quote(args[1])))
|
130
|
+
end
|
131
|
+
elsif args[1].class.name == 'Array'
|
132
|
+
args[1].each do |right|
|
133
|
+
or_sql.push(block.call(format_sql(args[0].to_s), quote(right)))
|
134
|
+
end
|
135
|
+
else
|
136
|
+
or_sql.push(block.call(format_sql(args[0].to_s), quote(args[1])))
|
137
|
+
end
|
138
|
+
and_sql.push("(" + or_sql.join(' or ') + ")")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
@join_list.each do |join|
|
142
|
+
and_sql.push(join[:table].generate_filter_conditions_sql)
|
143
|
+
end
|
144
|
+
and_sql.join(' and ')
|
145
|
+
end
|
146
|
+
|
147
|
+
def generate_table_list_sql
|
148
|
+
out = []
|
149
|
+
out.push(name)
|
150
|
+
@join_list.each do |join|
|
151
|
+
table_list_sql = join[:table].generate_table_list_sql
|
152
|
+
if table_list_sql != ''
|
153
|
+
out.push(table_list_sql)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
out.join(', ')
|
157
|
+
end
|
158
|
+
|
159
|
+
def generate_from_sql
|
160
|
+
"from " + generate_table_list_sql
|
161
|
+
end
|
162
|
+
|
163
|
+
def generate_join_condition_sql(table1, table2, foreign_key)
|
164
|
+
if !foreign_key.nil?
|
165
|
+
if table2.column? foreign_key
|
166
|
+
"#{table1.name}.id = #{table2.name}.#{foreign_key}"
|
167
|
+
else
|
168
|
+
"#{table1.name}.#{foreign_key} = #{table2.name}.id"
|
169
|
+
end
|
170
|
+
else
|
171
|
+
if table2.column? "#{table1.name}_id"
|
172
|
+
"#{table1.name}.id = #{table2.name}.#{table1.name}_id"
|
173
|
+
else
|
174
|
+
"#{table1.name}.#{table2.name}_id = #{table2.name}.id"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def generate_inner_join_conditions_sql
|
180
|
+
out = []
|
181
|
+
@join_list.each do |join|
|
182
|
+
out.push(generate_join_condition_sql(self, join[:table], join[:options][:using]))
|
183
|
+
inner_join_conditions_sql = join[:table].generate_inner_join_conditions_sql
|
184
|
+
if inner_join_conditions_sql != ''
|
185
|
+
out.push(inner_join_conditions_sql)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
out.join(" and ")
|
189
|
+
end
|
190
|
+
|
191
|
+
def generate_where_sql
|
192
|
+
out = []
|
193
|
+
inner_join_conditions_sql = generate_inner_join_conditions_sql
|
194
|
+
if inner_join_conditions_sql != ''
|
195
|
+
out.push inner_join_conditions_sql
|
196
|
+
end
|
197
|
+
filter_conditions_sql = generate_filter_conditions_sql
|
198
|
+
if filter_conditions_sql != ''
|
199
|
+
out.push filter_conditions_sql
|
200
|
+
end
|
201
|
+
out = out.join(' and ')
|
202
|
+
if out != ''
|
203
|
+
out = "where #{out}"
|
204
|
+
end
|
205
|
+
out
|
206
|
+
end
|
207
|
+
|
208
|
+
def generate_group_by_sql
|
209
|
+
if @join_list.count > 0
|
210
|
+
"group by #{name}.id"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def generate_order_by_sql
|
215
|
+
out = []
|
216
|
+
@order_by_list.each do |order_by|
|
217
|
+
(sql_expression, desc) = order_by
|
218
|
+
if desc
|
219
|
+
out.push "#{format_sql(sql_expression)} desc"
|
220
|
+
else
|
221
|
+
out.push "#{format_sql(sql_expression)} asc"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
@join_list.each do |join|
|
225
|
+
order_by_sql = join[:table].generate_order_by_sql
|
226
|
+
if order_by_sql != ''
|
227
|
+
out.push(order_by_sql)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
out = out.join(', ')
|
231
|
+
if out != ''
|
232
|
+
out = "order by #{out}"
|
233
|
+
end
|
234
|
+
out
|
235
|
+
end
|
236
|
+
|
237
|
+
def generate_select_sql(expression_list_sql, limit = nil)
|
238
|
+
if !limit.nil?
|
239
|
+
limit_sql = "limit #{limit}"
|
240
|
+
else
|
241
|
+
limit_sql = ''
|
242
|
+
end
|
243
|
+
"select #{format_sql(expression_list_sql)} #{generate_from_sql} #{generate_where_sql} #{generate_group_by_sql} #{generate_order_by_sql} #{limit_sql}"
|
244
|
+
end
|
245
|
+
|
246
|
+
def count(limit = nil)
|
247
|
+
@database.client.query(generate_select_sql('id', limit)).count
|
248
|
+
end
|
249
|
+
|
250
|
+
def all(limit = nil)
|
251
|
+
out = []
|
252
|
+
@database.client.query(generate_select_sql('id', limit), :as => :hash).each do |row|
|
253
|
+
out.push(Row.new(@database, @name, row['id']))
|
254
|
+
end
|
255
|
+
out
|
256
|
+
end
|
257
|
+
|
258
|
+
def each &block
|
259
|
+
all.each &block
|
260
|
+
nil
|
261
|
+
end
|
262
|
+
|
263
|
+
def first
|
264
|
+
all(1).first
|
265
|
+
end
|
266
|
+
|
267
|
+
def update(hash)
|
268
|
+
all.each {|row| row.update(hash)}
|
269
|
+
end
|
270
|
+
|
271
|
+
def delete
|
272
|
+
each {|row| row.delete}
|
273
|
+
end
|
274
|
+
|
275
|
+
def insert(hash)
|
276
|
+
@database.client.query("insert into `#{@name}`(#{(hash.map{|k,v| "`#{k}`"}).join(', ')}) values(#{(hash.map{|k,v| quote(v)}).join(', ')})")
|
277
|
+
end
|
278
|
+
|
279
|
+
def sum(sql_expression, limit = nil)
|
280
|
+
out = 0
|
281
|
+
@database.client.query(generate_select_sql("sum(#{sql_expression})", limit), :as => :array).each{|row| out += row.first}
|
282
|
+
out
|
283
|
+
end
|
284
|
+
|
285
|
+
def drop
|
286
|
+
eval("@table_names = nil", @database.bindings)
|
287
|
+
@database.client.query("drop table `#{@name}`")
|
288
|
+
end
|
289
|
+
|
290
|
+
def add(name, type, options = {})
|
291
|
+
case type
|
292
|
+
when :string
|
293
|
+
@database.client.query("alter table `#{@name}` add `#{name}` varchar(255) not null")
|
294
|
+
when :text
|
295
|
+
@database.client.query("alter table `#{@name}` add `#{name}` longtext not null")
|
296
|
+
when :binary
|
297
|
+
@database.client.query("alter table `#{@name}` add `#{name}` longblob not null")
|
298
|
+
when :integer
|
299
|
+
@database.client.query("alter table `#{@name}` add `#{name}` int signed not null")
|
300
|
+
when :foreign_key
|
301
|
+
@database.client.query("alter table `#{@name}` add `#{name}` int unsigned not null")
|
302
|
+
@database.client.query("alter table `#{@name}` add index(`#{name}`)")
|
303
|
+
when :date
|
304
|
+
@database.client.query("alter table `#{@name}` add `#{name}` date not null")
|
305
|
+
when :datetime
|
306
|
+
@database.client.query("alter table `#{@name}` add `#{name}` datetime not null")
|
307
|
+
when :boolean
|
308
|
+
@database.client.query("alter table `#{@name}` add `#{name}` enum('true', 'false') not null")
|
309
|
+
when :decimal
|
310
|
+
@database.client.query("alter table `#{@name}` add `#{name}` decimal not null")
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def remove(name)
|
315
|
+
@database.client.query("alter table `#{@name}` drop `#{name}`")
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
def column_names
|
320
|
+
@database.client.query("describe `#{@name}`", :as => :hash).map {|row| row['Field']}
|
321
|
+
end
|
322
|
+
|
323
|
+
def to_s
|
324
|
+
all.to_s
|
325
|
+
end
|
326
|
+
|
327
|
+
end
|
328
|
+
end
|
data/lib/rmap/version.rb
ADDED
data/lib/rmap.rb
ADDED
data/rmap.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rmap/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rmap"
|
7
|
+
s.version = Rmap::VERSION
|
8
|
+
s.authors = ["Jody Salt"]
|
9
|
+
s.email = ["jody@jodysalt.com"]
|
10
|
+
s.homepage = "https://github.com/jodysalt/rmap"
|
11
|
+
s.summary = "A simple yet powerful object relational mapper (ORM)."
|
12
|
+
|
13
|
+
s.rubyforge_project = "rmap"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
# specify any dependencies here; for example:
|
21
|
+
# s.add_development_dependency "rspec"
|
22
|
+
# s.add_runtime_dependency "rest-client"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rmap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jody Salt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-10 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email:
|
16
|
+
- jody@jodysalt.com
|
17
|
+
executables:
|
18
|
+
- rmap
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- README.markdown
|
25
|
+
- Rakefile
|
26
|
+
- bin/rmap
|
27
|
+
- lib/rmap.rb
|
28
|
+
- lib/rmap/database.rb
|
29
|
+
- lib/rmap/row.rb
|
30
|
+
- lib/rmap/table.rb
|
31
|
+
- lib/rmap/version.rb
|
32
|
+
- rmap.gemspec
|
33
|
+
homepage: https://github.com/jodysalt/rmap
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project: rmap
|
53
|
+
rubygems_version: 1.8.10
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: A simple yet powerful object relational mapper (ORM).
|
57
|
+
test_files: []
|