tsukasaoishi-miyazakiresistance 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -3,3 +3,7 @@ Manifest.txt
3
3
  README.rdoc
4
4
  Rakefile
5
5
  lib/miyazakiresistance.rb
6
+ lib/miyazaki_resistance/base.rb
7
+ lib/miyazaki_resistance/error.rb
8
+ lib/miyazaki_resistance/miyazaki_logger.rb
9
+ lib/miyazaki_resistance/tokyo_connection.rb
data/README.rdoc CHANGED
@@ -10,13 +10,13 @@ MiyazakiResistance is a library like ActiveRecord to use Tokyo Tyrant.
10
10
 
11
11
  require 'miyazaki_resistance'
12
12
  class Example < MiyazakiResistance::Base
13
- host_and_port "localhost", 1975
14
- host_and_port "slave", 1975, :readonly
15
- set_timeout 5
16
- set_column :name, :string
13
+ set_server "localhost", 1975, :write
14
+ set_server "slave", 1975, :standby
15
+ set_timeout 60
16
+ set_column :name, :string, :index
17
17
  set_column :age, :integer
18
18
  set_column :birthday, :date
19
- set_column :created_at, :datetime
19
+ set_column :created_at, :datetime, :index
20
20
  end
21
21
 
22
22
  == REQUIREMENTS:
@@ -0,0 +1,256 @@
1
+ module MiyazakiResistance
2
+ class Base
3
+ attr_accessor :id
4
+
5
+ def initialize(args = nil)
6
+ args ||= {}
7
+ self.id = nil
8
+ args.each do |key, value|
9
+ if key.empty?
10
+ key = :id
11
+ value = value.to_i
12
+ else
13
+ case self.class.all_columns[key.to_s]
14
+ when :integer
15
+ value = value.to_i
16
+ when :string
17
+ value = value.to_s
18
+ when :datetime
19
+ value = Time.at(value.to_i) unless value.is_a?(Time)
20
+ when :date
21
+ unless value.is_a?(Date)
22
+ time = Time.at(value.to_i)
23
+ value = Date.new(time.year, time.month, time.day)
24
+ end
25
+ end
26
+ end
27
+
28
+ self.__send__("#{key}=", value)
29
+ end
30
+ end
31
+
32
+ def save
33
+ time_column_check
34
+ con = write_connection
35
+ self.id = kaeru_timeout{con.genuid.to_i} if new_record?
36
+ kaeru_timeout {con.put(self.id, raw_attributes)}
37
+ rescue TimeoutError
38
+ remove_pool(con)
39
+ retry
40
+ end
41
+
42
+
43
+ def update_attributes(args)
44
+ raise NewRecordError if new_record?
45
+ attributes = args
46
+ save
47
+ end
48
+
49
+ def destroy
50
+ raise NewRecordError if new_record?
51
+ con = write_connection
52
+ kaeru_timeout{con.out(self.id)}
53
+ rescue TimeoutError
54
+ remove_pool(con)
55
+ retry
56
+ end
57
+
58
+ def attributes
59
+ hash = {}
60
+ self.class.all_columns.keys.each{|key| hash.update(key => self.__send__(key))}
61
+ hash
62
+ end
63
+
64
+ def attributes=(args)
65
+ args.each {|key, value| self.__send__("#{key}=", value)}
66
+ end
67
+
68
+ def new_record?
69
+ self.id.nil?
70
+ end
71
+
72
+ class << self
73
+ def find(first, args={})
74
+ case first.class.name
75
+ when "Fixnum"
76
+ find_by_id(first)
77
+ when "Array"
78
+ find_by_ids(first)
79
+ when "Symbol"
80
+ find_by_query(first, args)
81
+ else
82
+ raise ArgumentError
83
+ end
84
+ end
85
+
86
+ def find_by_query(mode, args={})
87
+ con = read_connection
88
+ query = TokyoTyrant::RDBQRY.new(con)
89
+
90
+ limit = (mode == :first ? 1 : args[:limit])
91
+ query = make_limit(query, limit, args[:offset])
92
+ query = make_order(query, args[:order])
93
+ query = make_conditions(query, args[:conditions])
94
+
95
+ now = Time.now
96
+ results = kaeru_timeout{query.searchget}.map{|r| self.new(r)}
97
+ limit.to_i == 1 ? results.first : results
98
+ rescue TimeoutError
99
+ remove_pool(con)
100
+ retry
101
+ end
102
+
103
+ def find_by_id(target)
104
+ find_by_ids([target])
105
+ end
106
+
107
+ def count(args = {})
108
+ con = read_connection
109
+ if args.empty?
110
+ kaeru_timeout{con.rnum}
111
+ else
112
+ query = TokyoTyrant::RDBQRY.new(con)
113
+ query = make_conditions(query, args[:conditions])
114
+ kaeru_timeout{query.search}.size
115
+ end
116
+ rescue TimeoutError
117
+ remove_pool(con)
118
+ retry
119
+ end
120
+
121
+ def create(args)
122
+ inst = self.new(args)
123
+ inst.save
124
+ inst
125
+ end
126
+ end
127
+
128
+ private
129
+
130
+ def raw_attributes
131
+ hash = {}
132
+ self.class.all_columns.each do |col, type|
133
+ value = self.__send__(col)
134
+ value = self.class.convert_date_to_i(value, type)
135
+ hash.update(col.to_s => value)
136
+ end
137
+ hash
138
+ end
139
+
140
+ def time_column_check
141
+ time_columns = ["updated"]
142
+ time_columns << "created" if new_record?
143
+ time_columns.each do |col|
144
+ %w|at on|.each do |type|
145
+ if self.class.all_columns.keys.include?("#{col}_#{type}")
146
+ now = Time.now
147
+ now = Date.new(now.year, now.month, now.day) if type == "on"
148
+ self.__send__("#{col}_#{type}=", now) if self.__send__("#{col}_#{type}").nil? || col == "updated"
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ def self.type_upcase(type)
155
+ case type
156
+ when :integer, :datetime, :date
157
+ "NUM"
158
+ when :string
159
+ "STR"
160
+ end
161
+ end
162
+
163
+ def self.find_by_ids(targets)
164
+ ret = Hash[*targets.map{|t| [t, nil]}.flatten]
165
+ con = read_connection
166
+ kaeru_timeout{con.mget(ret)}
167
+
168
+ ret.map do |r|
169
+ inst = self.new(r.last)
170
+ inst.id = r.first.to_i
171
+ inst
172
+ end
173
+ rescue TimeoutError
174
+ remove_pool(con)
175
+ retry
176
+ end
177
+
178
+ def self.make_limit(query, limit, offset)
179
+ query.setlimit(limit, offset) if limit
180
+ query
181
+ end
182
+
183
+ def self.make_order(query, order)
184
+ if order
185
+ target, order_type = order.split
186
+ if target == "id" || self.all_columns.keys.include?(target)
187
+ type = (target == "id" ? :integer : self.all_columns[target])
188
+ target = "" if target == "id"
189
+ order_type ||= "asc"
190
+ eval(%Q|query.setorder(target, TokyoTyrant::RDBQRY::QO#{type_upcase(type)}#{order_type.upcase})|)
191
+ end
192
+ end
193
+ query
194
+ end
195
+
196
+ def self.make_conditions(query, conditions)
197
+ if conditions
198
+ cond = conditions.first
199
+ param = conditions[1..-1]
200
+
201
+ col, ope, exp, type = nil, nil, nil, nil
202
+ not_flag = false
203
+ cond.split.each do |item|
204
+ next if %w|AND and|.include?(item)
205
+
206
+ if self.all_columns.keys.include?(item)
207
+ col = item
208
+ type = self.all_columns[item]
209
+ elsif item == "id"
210
+ col = ""
211
+ type = :integer
212
+ elsif OPERATIONS.keys.include?(item)
213
+ raise QueryError if col.nil? || type.nil?
214
+ work = type
215
+ work = :integer if DATE_TYPE.include?(work)
216
+ ope = OPERATIONS[item][work]
217
+ if not_flag
218
+ raise QueryError unless NOT_OPERATIONS.include?(item)
219
+ ope = ~ope
220
+ not_flag = false
221
+ end
222
+ elsif %w|NOT not|.include?(item)
223
+ not_flag = true
224
+ else
225
+ raise QueryError if col.nil? || type.nil? || ope.nil?
226
+ exp = (item == "?" ? param.shift : item)
227
+ if exp.is_a?(Array)
228
+ exp = exp.map{|e| plastic_data(e, type)}.join(" ")
229
+ else
230
+ exp = plastic_data(exp, type)
231
+ end
232
+ end
233
+
234
+ if col && type && ope && exp
235
+ query.addcond(col, ope, exp)
236
+ col, ope, exp, type = nil, nil, nil, nil
237
+ not_flag = false
238
+ end
239
+ end
240
+ end
241
+ query
242
+ end
243
+
244
+ def self.plastic_data(value, type)
245
+ ret = case type
246
+ when :datetime
247
+ value.to_i
248
+ when :date
249
+ Time.local(value.year, value.month, value.day).to_i
250
+ else
251
+ value
252
+ end
253
+ ret.to_s
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,9 @@
1
+ module MiyazakiResistance
2
+ class MiyazakiResistanceError < StandardError; end
3
+ class TokyoTyrantConnectError < MiyazakiResistanceError; end
4
+ class NewRecordError < MiyazakiResistanceError; end
5
+ class QueryError < MiyazakiResistanceError; end
6
+ class MasterDropError < MiyazakiResistanceError; end
7
+ class AllTimeoutORConnectionPoolEmpty < MiyazakiResistanceError; end
8
+ end
9
+
@@ -0,0 +1,27 @@
1
+ module MiyazakiResistance
2
+ module MiyazakiLogger
3
+ def self.included(base)
4
+ base.class_eval do
5
+ @@logger = nil
6
+ end
7
+ base.extend ClassMethods
8
+ base.__send__(:include, InstanceMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def logger
13
+ @@logger ||= Logger.new("miyazakiresistance.log")
14
+ end
15
+
16
+ def logger=(target)
17
+ @@logger = target
18
+ end
19
+ end
20
+
21
+ module InstanceMethods
22
+ def logger
23
+ self.class.logger
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,129 @@
1
+ module MiyazakiResistance
2
+ module TokyoConnection
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ base.__send__(:include, InstanceMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ attr_accessor :connection_pool
10
+ attr_accessor :all_columns
11
+ attr_accessor :all_indexes
12
+ attr_accessor :timeout_time
13
+
14
+ DEFAULT_TIMEOUT = 60
15
+
16
+ def set_server(host, port, target = :readonly)
17
+ logger.debug "set_server host : #{host} port : #{port} target : #{target}"
18
+
19
+ self.connection_pool ||= {:read => [], :write => nil, :standby => nil}
20
+ rdb = TokyoTyrant::RDBTBL.new
21
+ unless rdb.open(host, port)
22
+ logger.error "TokyoTyrantConnectError host : #{host} port : #{port} target : #{target}"
23
+ raise TokyoTyrantConnectError
24
+ end
25
+
26
+ self.connection_pool[:read] << rdb
27
+ self.connection_pool[:write] = rdb if target == :write
28
+ self.connection_pool[:standby] = rdb if target == :standby
29
+ end
30
+
31
+ def set_timeout(seconds)
32
+ self.timeout_time = seconds.to_i
33
+ end
34
+
35
+ def set_column(name, type, index = :no_index)
36
+ self.all_indexes ||= []
37
+ self.all_columns ||= {}
38
+ name = name.to_s
39
+ self.__send__(:attr_accessor, name)
40
+ self.all_columns.update(name => type)
41
+
42
+ set_index(name, type) if index == :index
43
+ end
44
+
45
+ def read_connection
46
+ check_pool
47
+ self.connection_pool[:read].sort_by{rand}.first
48
+ end
49
+
50
+ def write_connection
51
+ self.connection_pool[:write]
52
+ end
53
+
54
+ def remove_pool(rdb)
55
+ self.connection_pool[:read].delete_if{|pool| pool == rdb}
56
+ check_pool
57
+ fail_over if rdb == self.connection_pool[:write]
58
+ end
59
+
60
+ def kaeru_timeout(&block)
61
+ ret = nil
62
+ thread = Thread.new{ret = yield}
63
+ raise TimeoutError unless thread.join(self.timeout_time || DEFAULT_TIMEOUT)
64
+ ret
65
+ end
66
+
67
+ private
68
+
69
+ def all_connections
70
+ [self.connection_pool[:read], self.connection_pool[:write], self.connection_pool[:standby]].flatten.compact.uniq
71
+ end
72
+
73
+ def check_pool
74
+ return if self.connection_pool[:read] && !self.connection_pool[:read].empty?
75
+ logger.error "AllTimeoutORConnectionPoolEmpty"
76
+ raise AllTimeoutORConnectionPoolEmpty
77
+ end
78
+
79
+ def fail_over
80
+ unless self.connection_pool[:standby]
81
+ logger.error "MasterDropError"
82
+ raise MasterDropError
83
+ end
84
+
85
+ logger.info "master server failover"
86
+ self.connection_pool[:write] = self.connection_pool[:standby]
87
+ self.connection_pool[:standby] = nil
88
+ end
89
+
90
+ def set_index(name, type)
91
+ index_type = case type
92
+ when :integer, :datetime, :date
93
+ TokyoTyrant::RDBTBL::ITDECIMAL
94
+ when :string
95
+ TokyoTyrant::RDBTBL::ITLEXICAL
96
+ end
97
+
98
+ self.all_indexes << name
99
+ all_connections.each do |con|
100
+ begin
101
+ con.setindex(name, index_type)
102
+ con.setindex(name, TokyoTyrant::RDBTBL::ITOPT)
103
+ rescue TimeoutError
104
+ remove_pool(con)
105
+ retry
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ module InstanceMethods
112
+ def read_connection
113
+ self.class.read_connection
114
+ end
115
+
116
+ def write_connection
117
+ self.class.write_connection
118
+ end
119
+
120
+ def remove_pool(rdb)
121
+ self.class.remove_pool(rdb)
122
+ end
123
+
124
+ def kaeru_timeout(&block)
125
+ self.class.kaeru_timeout(&block)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -4,435 +4,37 @@ $:.unshift(File.dirname(__FILE__)) unless
4
4
  require 'tokyotyrant'
5
5
  require 'timeout'
6
6
  require 'logger'
7
+ require 'miyazaki_resistance/tokyo_connection'
8
+ require 'miyazaki_resistance/miyazaki_logger'
9
+ require 'miyazaki_resistance/base'
10
+ require 'miyazaki_resistance/error'
7
11
 
8
12
  module MiyazakiResistance
9
- VERSION = '0.0.2'
10
-
11
- class MiyazakiResistanceError < StandardError; end
12
- class TokyoTyrantConnectError < MiyazakiResistanceError; end
13
- class NewRecordError < MiyazakiResistanceError; end
14
- class QueryError < MiyazakiResistanceError; end
15
- class MasterDropError < MiyazakiResistanceError; end
16
- class AllTimeoutORConnectionPoolEmpty < MiyazakiResistanceError; end
17
-
18
- module TokyoConnection
19
- def self.included(base)
20
- base.extend ClassMethods
21
- base.__send__(:include, InstanceMethods)
22
- end
23
-
24
- module ClassMethods
25
- attr_accessor :connection_pool
26
- attr_accessor :all_columns
27
- attr_accessor :all_indexes
28
- attr_accessor :timeout_time
29
-
30
- def set_server(host, port, target = :readonly)
31
- logger.debug "set_server host : #{host} port : #{port} target : #{target}"
32
-
33
- self.connection_pool ||= {:read => [], :write => nil, :standby => nil}
34
- rdb = TokyoTyrant::RDBTBL.new
35
- unless rdb.open(host, port)
36
- logger.error "TokyoTyrantConnectError host : #{host} port : #{port} target : #{target}"
37
- raise TokyoTyrantConnectError
38
- end
39
-
40
- self.connection_pool[:read] << rdb
41
- self.connection_pool[:write] = rdb if target == :write
42
- self.connection_pool[:standby] = rdb if target == :standby
43
- end
44
-
45
- def set_timeout(seconds)
46
- self.timeout_time = seconds.to_i
47
- end
48
-
49
- def set_column(name, type, index = :no_index)
50
- self.all_indexes ||= []
51
- self.all_columns ||= {}
52
- name = name.to_s
53
- self.__send__(:attr_accessor, name)
54
- self.all_columns.update(name => type)
55
-
56
- set_index(name, type) if index == :index
57
- end
58
-
59
- def read_connection
60
- check_pool
61
- self.connection_pool[:read].sort_by{rand}.first
62
- end
63
-
64
- def write_connection
65
- self.connection_pool[:write]
66
- end
67
-
68
- def remove_pool(rdb)
69
- self.connection_pool[:read].delete_if{|pool| pool == rdb}
70
- check_pool
71
- fail_over if rdb == self.connection_pool[:write]
72
- end
73
-
74
- def kaeru_timeout(&block)
75
- ret = nil
76
- thread = Thread.new{ret = yield}
77
- raise TimeoutError unless thread.join(self.timeout_time)
78
- ret
79
- end
80
-
81
- private
82
-
83
- def all_connections
84
- [self.connection_pool[:read], self.connection_pool[:write], self.connection_pool[:standby]].flatten.compact.uniq
85
- end
86
-
87
- def check_pool
88
- return if self.connection_pool[:read] && !self.connection_pool[:read].empty?
89
- logger.error "AllTimeoutORConnectionPoolEmpty"
90
- raise AllTimeoutORConnectionPoolEmpty
91
- end
92
-
93
- def fail_over
94
- unless self.connection_pool[:standby]
95
- logger.error "MasterDropError"
96
- raise MasterDropError
97
- end
98
-
99
- logger.info "master server failover"
100
- self.connection_pool[:write] = self.connection_pool[:standby]
101
- self.connection_pool[:standby] = nil
102
- end
103
-
104
- def set_index(name, type)
105
- index_type = case type
106
- when :integer, :datetime, :date
107
- TokyoTyrant::RDBTBL::ITDECIMAL
108
- when :string
109
- TokyoTyrant::RDBTBL::ITLEXICAL
110
- end
111
-
112
- self.all_indexes << name
113
- all_connections.each do |con|
114
- begin
115
- con.setindex(name, index_type)
116
- rescue TimeoutError
117
- remove_pool(con)
118
- retry
119
- end
120
- end
121
- end
122
- end
123
-
124
- module InstanceMethods
125
- def read_connection
126
- self.class.read_connection
127
- end
128
-
129
- def write_connection
130
- self.class.write_connection
131
- end
132
-
133
- def remove_pool(rdb)
134
- self.class.remove_pool(rdb)
135
- end
136
-
137
- def kaeru_timeout(&block)
138
- self.class.kaeru_timeout(&block)
139
- end
140
- end
141
- end
142
-
143
- module MiyazakiLogger
144
- def self.included(base)
145
- base.class_eval do
146
- @@logger = nil
147
- end
148
- base.extend ClassMethods
149
- base.__send__(:include, InstanceMethods)
150
- end
151
-
152
- module ClassMethods
153
- def logger
154
- @@logger ||= Logger.new("miyazakiresistance.log")
155
- end
156
-
157
- def logger=(target)
158
- @@logger = target
159
- end
160
- end
161
-
162
- module InstanceMethods
163
- def logger
164
- self.class.logger
165
- end
166
- end
167
- end
168
-
169
- class Base
170
- include TokyoConnection
171
- include MiyazakiLogger
172
-
173
- OPERATIONS = {
174
- "=" => {:string => TokyoTyrant::RDBQRY::QCSTREQ, :integer => TokyoTyrant::RDBQRY::QCNUMEQ},
175
- "!=" => {:string => ~TokyoTyrant::RDBQRY::QCSTREQ, :integer => ~TokyoTyrant::RDBQRY::QCNUMEQ},
176
- "<>" => {:string => ~TokyoTyrant::RDBQRY::QCSTREQ, :integer => ~TokyoTyrant::RDBQRY::QCNUMEQ},
177
- "include" => {:string => TokyoTyrant::RDBQRY::QCSTRINC},
178
- "begin" => {:string => TokyoTyrant::RDBQRY::QCSTRBW},
179
- "end" => {:string => TokyoTyrant::RDBQRY::QCSTREW},
180
- "allinclude" => {:string => TokyoTyrant::RDBQRY::QCSTRAND},
181
- "anyinclude" => {:string => TokyoTyrant::RDBQRY::QCSTROR},
182
- "in" => {:string => TokyoTyrant::RDBQRY::QCSTROREQ, :integer => TokyoTyrant::RDBQRY::QCNUMOREQ},
183
- "=~" => {:string => TokyoTyrant::RDBQRY::QCSTRRX},
184
- "!~" => {:string => ~TokyoTyrant::RDBQRY::QCSTRRX},
185
- ">" => {:integer => TokyoTyrant::RDBQRY::QCNUMGT},
186
- ">=" => {:integer => TokyoTyrant::RDBQRY::QCNUMGE},
187
- "<" => {:integer => TokyoTyrant::RDBQRY::QCNUMLT},
188
- "<=" => {:integer => TokyoTyrant::RDBQRY::QCNUMLE},
189
- "between" => {:integer => TokyoTyrant::RDBQRY::QCNUMBT}
190
- }
191
- NOT_OPERATIONS = %w|include begin end allinclude anyinclude in between|
192
- DATE_TYPE = [:datetime, :date]
193
-
194
- attr_accessor :id
195
-
196
- def initialize(args = nil)
197
- args ||= {}
198
- self.id = nil
199
- args.each do |key, value|
200
- case self.class.all_columns[key.to_s]
201
- when :integer
202
- value = value.to_i
203
- when :string
204
- value = value.to_s
205
- when :datetime
206
- value = Time.at(value.to_i) unless value.is_a?(Time)
207
- when :date
208
- unless value.is_a?(Date)
209
- time = Time.at(value.to_i)
210
- value = Date.new(time.year, time.month, time.day)
211
- end
212
- end
213
-
214
- self.__send__("#{key}=", value)
215
- end
216
- end
217
-
218
- def save
219
- time_column_check
220
- con = write_connection
221
- self.id = kaeru_timeout{con.genuid.to_i} if new_record?
222
- kaeru_timeout {con.put(self.id, raw_attributes)}
223
- rescue TimeoutError
224
- remove_pool(con)
225
- retry
226
- end
227
-
228
-
229
- def update_attributes(args)
230
- raise NewRecordError if new_record?
231
- attributes = args
232
- save
233
- end
234
-
235
- def destroy
236
- raise NewRecordError if new_record?
237
- con = write_connection
238
- kaeru_timeout{con.out(self.id)}
239
- rescue TimeoutError
240
- remove_pool(con)
241
- retry
242
- end
243
-
244
- def attributes
245
- hash = {}
246
- self.class.all_columns.keys.each{|key| hash.update(key => self.__send__(key))}
247
- hash
248
- end
249
-
250
- def attributes=(args)
251
- args.each {|key, value| self.__send__("#{key}=", value)}
252
- end
253
-
254
- def new_record?
255
- self.id.nil?
256
- end
257
-
258
- class << self
259
- def find(first, args={})
260
- case first.class.name
261
- when "Fixnum"
262
- find_by_id(first)
263
- when "Array"
264
- find_by_ids(first)
265
- when "Symbol"
266
- find_by_query(first, args)
267
- else
268
- raise ArgumentError
269
- end
270
- end
271
-
272
- def find_by_query(mode, args={})
273
- con = read_connection
274
- query = TokyoTyrant::RDBQRY.new(con)
275
-
276
- limit = (mode == :first ? 1 : args[:limit])
277
- query = make_limit(query, limit, args[:offset])
278
- query = make_order(query, args[:order])
279
- query = make_conditions(query, args[:conditions])
280
-
281
- ids = kaeru_timeout{query.search}
282
- ret = find_by_ids(ids)
283
- ret = ret.first if limit.to_i == 1
284
- ret
285
- rescue TimeoutError
286
- remove_pool(con)
287
- retry
288
- end
289
-
290
- def find_by_id(target)
291
- find_by_ids([target])
292
- end
293
-
294
- def count(args = {})
295
- con = read_connection
296
- if args.empty?
297
- kaeru_timeout{con.rnum}
298
- else
299
- query = TokyoTyrant::RDBQRY.new(con)
300
- query = make_conditions(query, args[:conditions])
301
- kaeru_timeout{query.search}.size
302
- end
303
- rescue TimeoutError
304
- remove_pool(con)
305
- retry
306
- end
307
-
308
- def create(args)
309
- inst = self.new(args)
310
- inst.save
311
- inst
312
- end
313
- end
314
-
315
- private
316
-
317
- def raw_attributes
318
- hash = {}
319
- self.class.all_columns.each do |col, type|
320
- value = self.__send__(col)
321
- value = self.class.convert_date_to_i(value, type)
322
- hash.update(col.to_s => value)
323
- end
324
- hash
325
- end
326
-
327
- def time_column_check
328
- time_columns = ["updated"]
329
- time_columns << "created" if new_record?
330
- time_columns.each do |col|
331
- %w|at on|.each do |type|
332
- if self.class.all_columns.keys.include?("#{col}_#{type}")
333
- now = Time.now
334
- now = Date.new(now.year, now.month, now.day) if type == "on"
335
- self.__send__("#{col}_#{type}=", now) if self.__send__("#{col}_#{type}").nil? || col == "updated"
336
- end
337
- end
338
- end
339
- end
340
-
341
- def self.type_upcase(type)
342
- case type
343
- when :integer, :datetime, :date
344
- "NUM"
345
- when :string
346
- "STR"
347
- end
348
- end
349
-
350
- def self.find_by_ids(targets)
351
- targets.map do |key|
352
- begin
353
- con = read_connection
354
- data = kaeru_timeout{con.get(key)}
355
- inst = self.new(data)
356
- inst.id = key.to_i
357
- inst
358
- rescue TimeoutError
359
- remove_pool(con)
360
- retry
361
- end
362
- end
363
- end
364
-
365
- def self.make_limit(query, limit, offset)
366
- query.setlimit(limit, offset) if limit
367
- query
368
- end
369
-
370
- def self.make_order(query, order)
371
- if order
372
- target, order_type = order.split
373
- if target == "id" || self.all_columns.keys.include?(target)
374
- type = (target == "id" ? :integer : self.all_columns[target])
375
- target = "" if target == "id"
376
- order_type ||= "asc"
377
- eval(%Q|query.setorder(target, TokyoTyrant::RDBQRY::QO#{type_upcase(type)}#{order_type.upcase})|)
378
- end
379
- end
380
- query
381
- end
382
-
383
- def self.make_conditions(query, conditions)
384
- if conditions
385
- cond = conditions.first
386
- param = conditions[1..-1]
387
-
388
- col, ope, exp, type = nil, nil, nil, nil
389
- not_flag = false
390
- cond.split.each do |item|
391
- next if %w|AND and|.include?(item)
392
-
393
- if self.all_columns.keys.include?(item)
394
- col = item
395
- type = self.all_columns[item]
396
- elsif item == "id"
397
- col = ""
398
- type = :integer
399
- elsif OPERATIONS.keys.include?(item)
400
- raise QueryError if col.nil? || type.nil?
401
- work = type
402
- work = :integer if DATE_TYPE.include?(work)
403
- ope = OPERATIONS[item][work]
404
- if not_flag
405
- raise QueryError unless NOT_OPERATIONS.include?(item)
406
- ope = ~ope
407
- not_flag = false
408
- end
409
- elsif %w|NOT not|.include?(item)
410
- not_flag = true
411
- else
412
- raise QueryError if col.nil? || type.nil? || ope.nil?
413
- exp = (item == "?" ? param.shift : item)
414
- exp = convert_date_to_i(exp, type)
415
- end
416
-
417
- if col && type && ope && exp
418
- query.addcond(col, ope, exp.to_s)
419
- col, ope, exp, type = nil, nil, nil, nil
420
- not_flag = false
421
- end
422
- end
423
- end
424
- query
425
- end
13
+ VERSION = '0.0.3'
14
+ end
426
15
 
427
- def self.convert_date_to_i(value, type)
428
- case type
429
- when :datetime
430
- value.to_i
431
- when :date
432
- Time.local(value.year, value.month, value.day).to_i
433
- else
434
- value
435
- end
436
- end
437
- end
16
+ MiyazakiResistance::Base.class_eval do
17
+ include MiyazakiResistance::TokyoConnection
18
+ include MiyazakiResistance::MiyazakiLogger
19
+
20
+ OPERATIONS = {
21
+ "=" => {:string => TokyoTyrant::RDBQRY::QCSTREQ, :integer => TokyoTyrant::RDBQRY::QCNUMEQ},
22
+ "!=" => {:string => ~TokyoTyrant::RDBQRY::QCSTREQ, :integer => ~TokyoTyrant::RDBQRY::QCNUMEQ},
23
+ "<>" => {:string => ~TokyoTyrant::RDBQRY::QCSTREQ, :integer => ~TokyoTyrant::RDBQRY::QCNUMEQ},
24
+ "include" => {:string => TokyoTyrant::RDBQRY::QCSTRINC},
25
+ "begin" => {:string => TokyoTyrant::RDBQRY::QCSTRBW},
26
+ "end" => {:string => TokyoTyrant::RDBQRY::QCSTREW},
27
+ "allinclude" => {:string => TokyoTyrant::RDBQRY::QCSTRAND},
28
+ "anyinclude" => {:string => TokyoTyrant::RDBQRY::QCSTROR},
29
+ "in" => {:string => TokyoTyrant::RDBQRY::QCSTROREQ, :integer => TokyoTyrant::RDBQRY::QCNUMOREQ},
30
+ "=~" => {:string => TokyoTyrant::RDBQRY::QCSTRRX},
31
+ "!~" => {:string => ~TokyoTyrant::RDBQRY::QCSTRRX},
32
+ ">" => {:integer => TokyoTyrant::RDBQRY::QCNUMGT},
33
+ ">=" => {:integer => TokyoTyrant::RDBQRY::QCNUMGE},
34
+ "<" => {:integer => TokyoTyrant::RDBQRY::QCNUMLT},
35
+ "<=" => {:integer => TokyoTyrant::RDBQRY::QCNUMLE},
36
+ "between" => {:integer => TokyoTyrant::RDBQRY::QCNUMBT}
37
+ }
38
+ NOT_OPERATIONS = %w|include begin end allinclude anyinclude in between|
39
+ DATE_TYPE = [:datetime, :date]
438
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tsukasaoishi-miyazakiresistance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tsukasa OISHI
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-25 00:00:00 -07:00
12
+ date: 2009-03-26 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -49,6 +49,10 @@ files:
49
49
  - README.rdoc
50
50
  - Rakefile
51
51
  - lib/miyazakiresistance.rb
52
+ - lib/miyazaki_resistance/base.rb
53
+ - lib/miyazaki_resistance/error.rb
54
+ - lib/miyazaki_resistance/miyazaki_logger.rb
55
+ - lib/miyazaki_resistance/tokyo_connection.rb
52
56
  has_rdoc: true
53
57
  homepage: http://www.kaeruspoon.net/keywords/MiyazakiResistance
54
58
  post_install_message: PostInstall.txt