miyazakiresistance 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-03-21
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,11 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
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
10
+ lib/miyazaki_resistance/enhance.rb
11
+ initializers/rdb.rb
data/README.rdoc ADDED
@@ -0,0 +1,95 @@
1
+ = miyazakiresistance
2
+
3
+ * http://www.kaeruspoon.net/keywords/MiyazakiResistance
4
+
5
+ == DESCRIPTION:
6
+
7
+ MiyazakiResistance is a library like ActiveRecord to use Tokyo Tyrant.
8
+
9
+ == SYNOPSIS:
10
+
11
+ require 'miyazakiresistance'
12
+ class Example < MiyazakiResistance::Base
13
+ set_server "localhost", 1975, :write
14
+ set_server "slave", 1975, :standby
15
+ set_timeout 60
16
+ set_column :name, :string
17
+ set_column :age, :integer
18
+ set_column :birthday, :date
19
+ set_column :created_at, :datetime
20
+ end
21
+
22
+ work = Example.new
23
+ work.name = "tsukasa"
24
+ work.age = 34
25
+ work.birthday => Date.today
26
+ work.save
27
+
28
+ Example.create(:name => "oishi", :age => 14, :birthday => Date.today)
29
+
30
+ Example.count
31
+ Example.count(:conditions => ["name = ?", "oishi"])
32
+
33
+ Example.find(1)
34
+ Example.find([1,2])
35
+ Example.find(:first)
36
+ Example.find(:all)
37
+ Example.find(:all, :conditions => ["name = ? age = ?", "tsukasa", 34], :order => "created_at DESC", :offset => 1, :limit => 1)
38
+ Example.find_by_name("tsukasa")
39
+ Example.find_all_by_name_and_age("tsukasa", 34)
40
+
41
+
42
+ * You can write in config file
43
+
44
+ require 'miyazakiresistance'
45
+ class Example < MiyazakiResistance::Base
46
+ server_config Rails.env, "log/miyazakiresistance.yml"
47
+ set_timeout 60
48
+ set_column :name, :string
49
+ set_column :age, :integer
50
+ set_column :birthday, :date
51
+ set_column :created_at, :datetime
52
+ end
53
+
54
+ 'in log/miyazakiresistance.log'
55
+ developemnt:
56
+ set_server:
57
+ - server: localhost
58
+ port: 1975
59
+ role: write
60
+ - server: localhost
61
+ port: 1978
62
+ role: readonly
63
+
64
+ == REQUIREMENTS:
65
+
66
+ Tokyo Tyrant
67
+
68
+ == INSTALL:
69
+
70
+ * sudo gem install miyazakiresistance
71
+
72
+ == LICENSE:
73
+
74
+ (The MIT License)
75
+
76
+ Copyright (c) 2009 Tsukasa OISHI
77
+
78
+ Permission is hereby granted, free of charge, to any person obtaining
79
+ a copy of this software and associated documentation files (the
80
+ 'Software'), to deal in the Software without restriction, including
81
+ without limitation the rights to use, copy, modify, merge, publish,
82
+ distribute, sublicense, and/or sell copies of the Software, and to
83
+ permit persons to whom the Software is furnished to do so, subject to
84
+ the following conditions:
85
+
86
+ The above copyright notice and this permission notice shall be
87
+ included in all copies or substantial portions of the Software.
88
+
89
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
90
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
91
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
92
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
93
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
94
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
95
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/miyazakiresistance'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('miyazakiresistance', MiyazakiResistance::VERSION) do |p|
7
+ p.developer('Tsukasa OISHI', 'tsukasa.oishi@gmail.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ # p.extra_deps = [
12
+ # ['activesupport','>= 2.0.2'],
13
+ # ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
@@ -0,0 +1,13 @@
1
+ module TokyoTyrant
2
+ class RDB
3
+ attr_accessor :host, :port
4
+
5
+ def open_with_save_params(host, port = 0)
6
+ @host = host
7
+ @port = port
8
+ open_without_save_params(host, port)
9
+ end
10
+ alias_method :open_without_save_params, :open
11
+ alias_method :open, :open_with_save_params
12
+ end
13
+ end
@@ -0,0 +1,261 @@
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.is_a?(String) && 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
+ self
38
+ rescue TimeoutError
39
+ remove_pool(con)
40
+ retry
41
+ end
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
+ results = kaeru_timeout{query.searchget}.map{|r| self.new(r)}
96
+ limit.to_i == 1 ? results.first : results
97
+ rescue TimeoutError
98
+ remove_pool(con)
99
+ retry
100
+ end
101
+
102
+ def find_by_id(target)
103
+ find_by_ids([target]).first
104
+ end
105
+
106
+ def find_and_update(first, args={})
107
+ list = self.find(first, args)
108
+ list = [list] unless list.is_a?(Array)
109
+ list.each {|inst| yield(inst) and inst.save}
110
+ end
111
+
112
+ def count(args = {})
113
+ con = read_connection
114
+ if args.empty?
115
+ kaeru_timeout{con.rnum}
116
+ else
117
+ query = TokyoTyrant::RDBQRY.new(con)
118
+ query = make_conditions(query, args[:conditions])
119
+ kaeru_timeout{query.search.count}
120
+ end
121
+ rescue TimeoutError
122
+ remove_pool(con)
123
+ retry
124
+ end
125
+
126
+ def create(args)
127
+ self.new(args).save
128
+ end
129
+ end
130
+
131
+ private
132
+
133
+ def raw_attributes
134
+ hash = {}
135
+ self.class.all_columns.each do |col, type|
136
+ value = self.__send__(col)
137
+ value = self.class.plastic_data(value, type)
138
+ hash.update(col.to_s => value)
139
+ end
140
+ hash
141
+ end
142
+
143
+ def time_column_check
144
+ time_columns = ["updated"]
145
+ time_columns << "created" if new_record?
146
+ time_columns.each do |col|
147
+ %w|at on|.each do |type|
148
+ if self.class.all_columns.keys.include?("#{col}_#{type}")
149
+ now = Time.now
150
+ now = Date.new(now.year, now.month, now.day) if type == "on"
151
+ self.__send__("#{col}_#{type}=", now) if self.__send__("#{col}_#{type}").nil? || col == "updated"
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ def self.type_upcase(type)
158
+ case type
159
+ when :integer, :datetime, :date
160
+ "NUM"
161
+ when :string
162
+ "STR"
163
+ end
164
+ end
165
+
166
+ def self.find_by_ids(targets)
167
+ ret = Hash[*targets.map{|t| [t, nil]}.flatten]
168
+ con = read_connection
169
+ kaeru_timeout{con.mget(ret)}
170
+
171
+ ret.map do |r|
172
+ inst = self.new(r.last)
173
+ inst.id = r.first.to_i
174
+ inst
175
+ end
176
+ rescue TimeoutError
177
+ remove_pool(con)
178
+ retry
179
+ end
180
+
181
+ def self.make_limit(query, limit, offset)
182
+ query.setlimit(limit, offset) if limit
183
+ query
184
+ end
185
+
186
+ def self.make_order(query, order)
187
+ if order
188
+ target, order_type = order.split
189
+ if target == "id" || self.all_columns.keys.include?(target)
190
+ type = (target == "id" ? :integer : self.all_columns[target])
191
+ target = "" if target == "id"
192
+ order_type ||= "asc"
193
+ eval(%Q|query.setorder(target, TokyoTyrant::RDBQRY::QO#{type_upcase(type)}#{order_type.upcase})|)
194
+ end
195
+ end
196
+ query
197
+ end
198
+
199
+ def self.make_conditions(query, conditions)
200
+ if conditions
201
+ add_cond_list = []
202
+ cond = conditions.first
203
+ param = conditions[1..-1]
204
+
205
+ col, ope, exp, type = nil, nil, nil, nil
206
+ not_flag = false
207
+ cond.split.each do |item|
208
+ next if %w|AND and|.include?(item)
209
+
210
+ if self.all_columns.keys.include?(item)
211
+ col = item
212
+ type = self.all_columns[item]
213
+ elsif item == "id"
214
+ col = ""
215
+ type = :integer
216
+ elsif OPERATIONS.keys.include?(item)
217
+ raise QueryError if col.nil? || type.nil?
218
+ work = type
219
+ work = :integer if DATE_TYPE.include?(work)
220
+ ope = OPERATIONS[item][work]
221
+ if not_flag
222
+ raise QueryError unless NOT_OPERATIONS.include?(item)
223
+ ope = TokyoTyrant::RDBQRY::QCNEGATE | ope
224
+ not_flag = false
225
+ end
226
+ elsif %w|NOT not|.include?(item)
227
+ not_flag = true
228
+ else
229
+ raise QueryError if col.nil? || type.nil? || ope.nil?
230
+ exp = (item == "?" ? param.shift : item)
231
+ if exp.is_a?(Array)
232
+ exp = exp.map{|e| plastic_data(e, type)}.join(" ")
233
+ else
234
+ exp = plastic_data(exp, type)
235
+ end
236
+ end
237
+
238
+ if col && type && ope && exp
239
+ add_cond_list << [col, ope, exp]
240
+ col, ope, exp, type = nil, nil, nil, nil
241
+ not_flag = false
242
+ end
243
+ end
244
+ add_cond_list.reverse.each{|acl| query.addcond(*acl)}
245
+ end
246
+ query
247
+ end
248
+
249
+ def self.plastic_data(value, type)
250
+ ret = case type
251
+ when :datetime
252
+ value.to_i
253
+ when :date
254
+ Time.local(value.year, value.month, value.day).to_i
255
+ else
256
+ value
257
+ end
258
+ ret.to_s
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,43 @@
1
+ module MiyazakiResistance
2
+ module Enhance
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def method_missing(name, *arguments, &block)
9
+ if match = finder_attribute_names(name)
10
+ finder = match[:finder]
11
+ conditions = match[:cols].map{|col| "#{col} = ?"}.join(" ")
12
+
13
+ self.class_eval %Q|
14
+ def self.#{name}(*args)
15
+ options = args.last.is_a?(::Hash) ? pop : {}
16
+ options.update(:conditions => ["#{conditions}", args].flatten)
17
+ self.find(:#{finder}, options)
18
+ end
19
+ |
20
+
21
+ __send__(name, *arguments)
22
+ else
23
+ super
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def finder_attribute_names(name)
30
+ ret = {:finder => :first, :cols => nil}
31
+ if name.to_s =~ /^find_(all_by|by)_([_a-zA-Z]\w*)$/
32
+ ret[:finder] = :all if $1 == "all_by"
33
+ if cols = $2
34
+ cols = cols.split("_and_")
35
+ all_cols = self.all_columns.keys
36
+ ret[:cols] = cols if cols.all?{|col| all_cols.include?(col)}
37
+ end
38
+ end
39
+ (ret[:cols].nil? || ret[:cols].empty?) ? nil : ret
40
+ end
41
+ end
42
+ end
43
+ 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,57 @@
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
+ class_variable_get("@@logger") || (logger = Logger.new(default_log_file_path))
14
+ end
15
+
16
+ def logger=(target)
17
+ class_variable_set("@@logger", target)
18
+ end
19
+
20
+ %w|fatal error warn info debug|.each do|level|
21
+ self.class_eval %Q|
22
+ def logger_#{level}(str)
23
+ put_log(str, "#{level}")
24
+ end
25
+ |
26
+ end
27
+
28
+ private
29
+
30
+ def put_log(str, level)
31
+ logger.__send__(level, log_msg(str))
32
+ end
33
+
34
+ def log_msg(str)
35
+ "[#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}] #{str}"
36
+ end
37
+
38
+ def default_log_file_path
39
+ File.directory?("log") ? "log/miyazakiresistance.log" : "miyazakiresistance.log"
40
+ end
41
+ end
42
+
43
+ module InstanceMethods
44
+ def logger
45
+ self.class.logger
46
+ end
47
+
48
+ %w|fatal error warn info debug|.each do|level|
49
+ self.class_eval %Q|
50
+ def logger_#{level}(str)
51
+ self.class.logger_#{level}g(str)
52
+ end
53
+ |
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,137 @@
1
+ require 'yaml'
2
+ module MiyazakiResistance
3
+ module TokyoConnection
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.__send__(:include, InstanceMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :connection_pool
11
+ attr_accessor :all_columns
12
+ attr_accessor :timeout_time
13
+
14
+ DEFAULT = {
15
+ :timeout => 60,
16
+ :config => "miyazakiresistance.yml",
17
+ :port => 1978,
18
+ :role => :readonly
19
+ }
20
+
21
+ def server_config(env, file = DEFAULT[:config])
22
+ env = env.to_s
23
+ conf = YAML.load_file(file)
24
+
25
+ if (config = conf[env]).nil?
26
+ logger_fatal "specified environment(#{env}) is not found in conig file(#{file})"
27
+ return
28
+ end
29
+
30
+ config["set_server"].each do |work|
31
+ set_server work["server"], work["port"], work["role"]
32
+ end
33
+ rescue Errno::ENOENT => e
34
+ logger_fatal "config file is not found : #{file}"
35
+ end
36
+
37
+ def set_server(host, port = DEFAULT[:port], role = DEFAULT[:role])
38
+ self.connection_pool ||= {:read => [], :write => nil, :standby => nil}
39
+ rdb = TokyoTyrant::RDBTBL.new
40
+ logger_info "set server host : #{host} port : #{port} role : #{role}"
41
+
42
+ unless rdb.open(host.to_s, port)
43
+ logger_fatal "TokyoTyrantConnectError host : #{host} port : #{port} role : #{role}"
44
+ raise TokyoTyrantConnectError
45
+ end
46
+
47
+ self.connection_pool[:read] << rdb
48
+ self.connection_pool[:write] = rdb if role.to_sym == :write
49
+ self.connection_pool[:standby] = rdb if role.to_sym == :standby
50
+ end
51
+
52
+ def set_timeout(seconds)
53
+ self.timeout_time = seconds.to_i
54
+ end
55
+
56
+ def set_column(name, type, index = :no_index)
57
+ self.all_columns ||= {}
58
+ name = name.to_s
59
+ self.__send__(:attr_accessor, name)
60
+ self.all_columns.update(name => type)
61
+ end
62
+
63
+ def read_connection
64
+ check_pool
65
+ self.connection_pool[:read].sort_by{rand}.first
66
+ end
67
+
68
+ def write_connection
69
+ self.connection_pool[:write]
70
+ end
71
+
72
+ def remove_pool(rdb)
73
+ self.connection_pool[:read].delete_if{|pool| pool == rdb}
74
+
75
+ host, port = rdb.host, rdb.port
76
+ new_rdb = TokyoTyrant::RDBTBL.new
77
+ if new_rdb.open(host, port)
78
+ self.connection_pool[:read] << new_rdb
79
+ self.connection_pool[:write] = new_rdb if rdb == self.connection_pool[:write]
80
+ else
81
+ logger_fatal "remove pool : host #{host} port : #{port}"
82
+ check_pool
83
+ fail_over if rdb == self.connection_pool[:write]
84
+ end
85
+ rdb.close
86
+ end
87
+
88
+ def kaeru_timeout(&block)
89
+ ret = nil
90
+ thread = Thread.new{ret = yield}
91
+ raise TimeoutError, "tokyo tyrant server response error" unless thread.join(self.timeout_time || DEFAULT[:timeout])
92
+ ret
93
+ end
94
+
95
+ private
96
+
97
+ def all_connections
98
+ [self.connection_pool[:read], self.connection_pool[:write], self.connection_pool[:standby]].flatten.compact.uniq
99
+ end
100
+
101
+ def check_pool
102
+ return if self.connection_pool[:read] && !self.connection_pool[:read].empty?
103
+ logger_fatal "AllTimeoutORConnectionPoolEmpty"
104
+ raise AllTimeoutORConnectionPoolEmpty
105
+ end
106
+
107
+ def fail_over
108
+ unless self.connection_pool[:standby]
109
+ logger_fatal "MasterDropError"
110
+ raise MasterDropError
111
+ end
112
+
113
+ logger_fatal "master server failover"
114
+ self.connection_pool[:write] = self.connection_pool[:standby]
115
+ self.connection_pool[:standby] = nil
116
+ end
117
+ end
118
+
119
+ module InstanceMethods
120
+ def read_connection
121
+ self.class.read_connection
122
+ end
123
+
124
+ def write_connection
125
+ self.class.write_connection
126
+ end
127
+
128
+ def remove_pool(rdb)
129
+ self.class.remove_pool(rdb)
130
+ end
131
+
132
+ def kaeru_timeout(&block)
133
+ self.class.kaeru_timeout(&block)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,40 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'logger'
5
+ require 'timeout'
6
+ require 'tokyotyrant'
7
+
8
+ Dir.glob("#{File.join(File.dirname(__FILE__), "../initializers")}/*.rb").each{|path| require path}
9
+ Dir.glob("#{File.join(File.dirname(__FILE__), "miyazaki_resistance")}/*.rb").each{|path| require path}
10
+
11
+ module MiyazakiResistance
12
+ VERSION = '0.1.3'
13
+ end
14
+
15
+ MiyazakiResistance::Base.class_eval do
16
+ include MiyazakiResistance::TokyoConnection
17
+ include MiyazakiResistance::Enhance
18
+ include MiyazakiResistance::MiyazakiLogger
19
+
20
+ OPERATIONS = {
21
+ "=" => {:string => TokyoTyrant::RDBQRY::QCSTREQ, :integer => TokyoTyrant::RDBQRY::QCNUMEQ},
22
+ "!=" => {:string => TokyoTyrant::RDBQRY::QCNEGATE | TokyoTyrant::RDBQRY::QCSTREQ, :integer => TokyoTyrant::RDBQRY::QCNEGATE | TokyoTyrant::RDBQRY::QCNUMEQ},
23
+ "<>" => {:string => TokyoTyrant::RDBQRY::QCNEGATE | TokyoTyrant::RDBQRY::QCSTREQ, :integer => TokyoTyrant::RDBQRY::QCNEGATE | 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::QCNEGATE | 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]
40
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: miyazakiresistance
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Tsukasa OISHI
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-16 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: MiyazakiResistance is a library like ActiveRecord to use Tokyo Tyrant.
36
+ email:
37
+ - tsukasa.oishi@gmail.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - README.rdoc
46
+ files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.rdoc
50
+ - Rakefile
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
56
+ - lib/miyazaki_resistance/enhance.rb
57
+ - initializers/rdb.rb
58
+ has_rdoc: true
59
+ homepage: http://www.kaeruspoon.net/keywords/MiyazakiResistance
60
+ licenses: []
61
+
62
+ post_install_message: PostInstall.txt
63
+ rdoc_options:
64
+ - --main
65
+ - README.rdoc
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project: miyazakiresistance
83
+ rubygems_version: 1.3.5
84
+ signing_key:
85
+ specification_version: 2
86
+ summary: MiyazakiResistance is a library like ActiveRecord to use Tokyo Tyrant.
87
+ test_files: []
88
+