yore 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +22 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +48 -0
- data/Rakefile +57 -0
- data/bin/yore +65 -0
- data/lib/ihl_ruby/enum.rb +50 -0
- data/lib/ihl_ruby/extend_base_classes.rb +313 -0
- data/lib/ihl_ruby/misc_utils.rb +454 -0
- data/lib/ihl_ruby/string_utils.rb +53 -0
- data/lib/ihl_ruby/xml_utils.rb +163 -0
- data/lib/yore/yore_core.rb +491 -0
- data/lib/yore.orig.rb +6 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/rewind_spec.rb +187 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/test_job_a.xml +19 -0
- data/spec/yore_spec.rb +199 -0
- data/tasks/rspec.rake +21 -0
- metadata +128 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
bin/yore
|
2
|
+
History.txt
|
3
|
+
lib/ihl_ruby/enum.rb
|
4
|
+
lib/ihl_ruby/extend_base_classes.rb
|
5
|
+
lib/ihl_ruby/misc_utils.rb
|
6
|
+
lib/ihl_ruby/string_utils.rb
|
7
|
+
lib/ihl_ruby/xml_utils.rb
|
8
|
+
lib/yore.orig.rb
|
9
|
+
lib/yore/yore_core.rb
|
10
|
+
Manifest.txt
|
11
|
+
PostInstall.txt
|
12
|
+
Rakefile
|
13
|
+
README.rdoc
|
14
|
+
script/console
|
15
|
+
script/destroy
|
16
|
+
script/generate
|
17
|
+
spec/rewind_spec.rb
|
18
|
+
spec/spec.opts
|
19
|
+
spec/spec_helper.rb
|
20
|
+
spec/test_job_a.xml
|
21
|
+
spec/yore_spec.rb
|
22
|
+
tasks/rspec.rake
|
data/PostInstall.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
= yore
|
2
|
+
|
3
|
+
* FIX (url)
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
FIX (describe your package)
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* FIX (list of features or problems)
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
FIX (code sample of usage)
|
16
|
+
|
17
|
+
== REQUIREMENTS:
|
18
|
+
|
19
|
+
* FIX (list of requirements)
|
20
|
+
|
21
|
+
== INSTALL:
|
22
|
+
|
23
|
+
* FIX (sudo gem install, anything else)
|
24
|
+
|
25
|
+
== LICENSE:
|
26
|
+
|
27
|
+
(The MIT License)
|
28
|
+
|
29
|
+
Copyright (c) 2009 FIXME full name
|
30
|
+
|
31
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
32
|
+
a copy of this software and associated documentation files (the
|
33
|
+
'Software'), to deal in the Software without restriction, including
|
34
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
35
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
36
|
+
permit persons to whom the Software is furnished to do so, subject to
|
37
|
+
the following conditions:
|
38
|
+
|
39
|
+
The above copyright notice and this permission notice shall be
|
40
|
+
included in all copies or substantial portions of the Software.
|
41
|
+
|
42
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
43
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
44
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
45
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
46
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
47
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
48
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
6
|
+
require File.dirname(__FILE__) + '/lib/yore.orig'
|
7
|
+
|
8
|
+
# built following http://newgem.rubyforge.org/
|
9
|
+
# using RSpec option
|
10
|
+
# and had to add processor_ids from dr nic :
|
11
|
+
# http://groups.google.com/group/new-gem-generator/browse_thread/thread/648f70da782e607a/928ea0fe8319d886?lnk=raot
|
12
|
+
|
13
|
+
# Generate all the Rake tasks
|
14
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
15
|
+
$hoe = Hoe.new('yore', Yore::VERSION) do |p|
|
16
|
+
p.developer('Gary McGhee', 'contact@buzz@ware@com@au')
|
17
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
18
|
+
#p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
|
19
|
+
p.rubyforge_name = 'buzzware' #p.name # TODO this is default value
|
20
|
+
p.extra_deps = [
|
21
|
+
['RequirePaths','>= 1.0.1'],
|
22
|
+
['cmdparse', '>= 2.0.2'],
|
23
|
+
['s3sync', '>= 1.2.5']
|
24
|
+
]
|
25
|
+
p.extra_dev_deps = [
|
26
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
27
|
+
]
|
28
|
+
|
29
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
30
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
31
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
32
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
36
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
37
|
+
|
38
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
39
|
+
# task :default => [:spec, :features]
|
40
|
+
# this was generated by netbeans
|
41
|
+
# Rake::RDocTask.new do |rdoc|
|
42
|
+
# files =['README', 'LICENSE', 'lib/**/*.rb']
|
43
|
+
# rdoc.rdoc_files.add(files)
|
44
|
+
# rdoc.main = "README" # page to start on
|
45
|
+
# rdoc.title = "yore Docs"
|
46
|
+
# rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
47
|
+
# rdoc.options << '--line-numbers'
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# Rake::TestTask.new do |t|
|
51
|
+
# t.test_files = FileList['test/**/*.rb']
|
52
|
+
# end
|
53
|
+
|
54
|
+
Spec::Rake::SpecTask.new do |t|
|
55
|
+
t.spec_files = FileList['spec/**/*.rb']
|
56
|
+
end
|
57
|
+
|
data/bin/yore
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
gem 'RequirePaths'; require 'require_paths'
|
7
|
+
require_paths '.','../../..','/Users/gary/repos/Buzzware/projects_2009/yore/lib'
|
8
|
+
|
9
|
+
gem 'cmdparse'; require 'cmdparse'
|
10
|
+
|
11
|
+
require 'ihl_ruby/misc_utils'
|
12
|
+
require 'ihl_ruby/xml_utils'
|
13
|
+
require 'ihl_ruby/extend_base_classes'
|
14
|
+
|
15
|
+
require 'yore/yore_core'
|
16
|
+
|
17
|
+
CMD_OPTIONS = {} # options given on command line
|
18
|
+
|
19
|
+
# this contains a block that actually creates the controller, yore
|
20
|
+
def command(aParser,aController,aAction,aShortDescription=nil,aOptionParser=nil,aOther={})
|
21
|
+
c = CmdParse::Command.new( aAction.to_s, false )
|
22
|
+
c.short_desc = aShortDescription
|
23
|
+
c.description = aOther[:description] if aOther[:description]
|
24
|
+
c.options = aOptionParser if aOptionParser
|
25
|
+
c.set_execution_block do |args|
|
26
|
+
job = args.first
|
27
|
+
xmlRoot = XmlUtils.get_file_root(job)
|
28
|
+
aController.configure(xmlRoot,CMD_OPTIONS,{:basepath => File.dirname(File.expand_path(job))})
|
29
|
+
aController.send(aAction,args)
|
30
|
+
end
|
31
|
+
aParser.add_command(c)
|
32
|
+
end
|
33
|
+
|
34
|
+
cmd = CmdParse::CommandParser.new( true )
|
35
|
+
cmd.program_name = "yore"
|
36
|
+
cmd.program_version = [0, 0, 1]
|
37
|
+
# Options are given after a command and before arguments on the command line
|
38
|
+
# so global options are given first, before the first command
|
39
|
+
# ie ruby yore.rb --global_option command --command_option argument1 argument2 argumentn
|
40
|
+
cmd.options = CmdParse::OptionParserWrapper.new do |opt|
|
41
|
+
opt.separator "Global options:"
|
42
|
+
opt.on("--verbose", "Be verbose when outputting info") do |t|
|
43
|
+
CMD_OPTIONS[:verbose] = t
|
44
|
+
end
|
45
|
+
end
|
46
|
+
cmd.add_command( CmdParse::HelpCommand.new )
|
47
|
+
cmd.add_command( CmdParse::VersionCommand.new )
|
48
|
+
|
49
|
+
yore = YoreCore::Yore.new # main program object
|
50
|
+
|
51
|
+
# these options must be given after backup and before arguments
|
52
|
+
option_parser = CmdParse::OptionParserWrapper.new do |opt|
|
53
|
+
opt.on( '--all', 'Delete all IP addresses' ) do
|
54
|
+
CMD_OPTIONS[:deleteAll] = true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
command(cmd,yore,:backup,"Backup filelist to S3",option_parser)
|
59
|
+
|
60
|
+
command(cmd,yore,:test_email,"Test email sending\n")
|
61
|
+
|
62
|
+
command(cmd,yore,:db_dump,"Dump database by name in job\n")
|
63
|
+
|
64
|
+
cmd.parse
|
65
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Kernel
|
2
|
+
# simple (sequential) enumerated values
|
3
|
+
# usage :
|
4
|
+
#
|
5
|
+
# module Constants
|
6
|
+
# module Gradient
|
7
|
+
# enum :B, :A, :C
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# then :
|
12
|
+
#
|
13
|
+
# puts Constants::Gradient::B -> 0
|
14
|
+
# puts Constants::Gradient::C -> 2
|
15
|
+
# puts Constants::Gradient::MINVALUE -> 0
|
16
|
+
# puts Constants::Gradient::MAXVALUE -> 2
|
17
|
+
# puts Constants::Gradient::NAMES -> [:B, :A, :C]
|
18
|
+
# puts Constants::Gradient[0] -> :B
|
19
|
+
# puts Constants::Gradient[1] -> :A
|
20
|
+
# puts Constants::Gradient[2] -> :C
|
21
|
+
|
22
|
+
def enum(*syms)
|
23
|
+
syms.each_index { |i|
|
24
|
+
const_set(syms[i], i)
|
25
|
+
}
|
26
|
+
const_set(:NAMES, syms || [])
|
27
|
+
const_set(:MINVALUE, syms==nil ? nil : 0)
|
28
|
+
const_set(:MAXVALUE, syms==nil ? nil : syms.length-1)
|
29
|
+
const_set(:VALUECOUNT, syms==nil ? nil : syms.length)
|
30
|
+
const_set(:ALL, syms==nil ? [] : (0..syms.length-1).to_a)
|
31
|
+
const_set(:HUMAN_NAMES, syms.map{|n| n.to_s.humanize} || [])
|
32
|
+
|
33
|
+
# this returns the enum name given the value
|
34
|
+
def self.[]( idx )
|
35
|
+
(idx.is_a? Integer) ? const_get(:NAMES)[idx] : nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.valid?(idx)
|
39
|
+
(idx.is_a? Integer) && (idx >= 0) && (idx <= const_get(:MAXVALUE))
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.parse(name,default=nil)
|
43
|
+
return default if name.nil? || name.empty?
|
44
|
+
return default if not name = name.to_sym
|
45
|
+
result = const_get(:NAMES).index(name)
|
46
|
+
return result==nil ? default : result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,313 @@
|
|
1
|
+
String.class_eval do
|
2
|
+
def pad_left(value)
|
3
|
+
increase = value-self.length
|
4
|
+
return self if increase==0
|
5
|
+
if increase > 0
|
6
|
+
return self + ' '*increase
|
7
|
+
else
|
8
|
+
return self[0,value]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def pad_right(value)
|
13
|
+
increase = value-self.length
|
14
|
+
return self if increase==0
|
15
|
+
if increase > 0
|
16
|
+
return ' '*increase + self
|
17
|
+
else
|
18
|
+
return self[0,value]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Like chomp! but operates on the leading characters instead.
|
23
|
+
# The aString parameter would not normally be used.
|
24
|
+
def bite!(aValue=$/,aString=self)
|
25
|
+
if aString[0,aValue.length] == aValue
|
26
|
+
aString[0,aValue.length] = ''
|
27
|
+
return aString
|
28
|
+
else
|
29
|
+
return aString
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def bite(aValue=$/)
|
34
|
+
bite!(aValue,self.clone)
|
35
|
+
end
|
36
|
+
|
37
|
+
def begins_with?(aString)
|
38
|
+
self[0,aString.length]==aString
|
39
|
+
end
|
40
|
+
|
41
|
+
def ends_with?(aString)
|
42
|
+
self[-aString.length,aString.length]==aString
|
43
|
+
end
|
44
|
+
|
45
|
+
# for future methods
|
46
|
+
# def centre_bar(aChar = '-', indent = 6)
|
47
|
+
# (' '*indent) + aChar*(@width-(indent*2)) + (' '*indent)
|
48
|
+
# end
|
49
|
+
# def replace_string(aString,aCol,aSubString)
|
50
|
+
# return aString if aSubString==nil || aSubString==''
|
51
|
+
#
|
52
|
+
# aSubString = aSubString.to_s
|
53
|
+
# start_col = aCol < 0 ? 0 : aCol
|
54
|
+
# end_col = aCol+aSubString.length-1
|
55
|
+
# end_col = @width-1 if end_col >= @width
|
56
|
+
# source_len = end_col-start_col+1
|
57
|
+
# return aString if source_len <= 0 || end_col < 0 || start_col >= @width
|
58
|
+
# aString += ' '*((end_col+1) - aString.length) if aString.length < end_col+1
|
59
|
+
# aString[start_col,source_len] = aSubString[start_col-aCol,end_col-start_col+1]
|
60
|
+
# return aString
|
61
|
+
# end
|
62
|
+
|
63
|
+
def to_integer(aDefault=nil)
|
64
|
+
t = self.strip
|
65
|
+
return aDefault if t.empty? || !t.index(/^-{0,1}[0-9]+$/)
|
66
|
+
return t.to_i
|
67
|
+
end
|
68
|
+
|
69
|
+
def is_i?
|
70
|
+
self.to_integer(false) and true
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_float(aDefault=nil)
|
74
|
+
t = self.strip
|
75
|
+
return aDefault if !t =~ /(\+|-)?([0-9]+\.?[0-9]*|\.[0-9]+)([eE](\+|-)?[0-9]+)?/
|
76
|
+
return t.to_f
|
77
|
+
end
|
78
|
+
|
79
|
+
def is_f?
|
80
|
+
self.to_float(false) and true
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
Time.class_eval do
|
87
|
+
|
88
|
+
if !respond_to?(:change) # no activesupport loaded
|
89
|
+
def change(options)
|
90
|
+
::Time.send(
|
91
|
+
self.utc? ? :utc : :local,
|
92
|
+
options[:year] || self.year,
|
93
|
+
options[:month] || self.month,
|
94
|
+
options[:day] || self.day,
|
95
|
+
options[:hour] || self.hour,
|
96
|
+
options[:min] || (options[:hour] ? 0 : self.min),
|
97
|
+
options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
|
98
|
+
options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
def seconds_since_midnight
|
103
|
+
self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
|
104
|
+
end
|
105
|
+
|
106
|
+
def beginning_of_day
|
107
|
+
(self - self.seconds_since_midnight).change(:usec => 0)
|
108
|
+
end
|
109
|
+
|
110
|
+
alias :midnight :beginning_of_day
|
111
|
+
alias :at_midnight :beginning_of_day
|
112
|
+
alias :at_beginning_of_day :beginning_of_day
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
# offset of local machine from UTC, in seconds eg +9.hours
|
117
|
+
def self.local_offset
|
118
|
+
local(2000).utc_offset
|
119
|
+
end
|
120
|
+
|
121
|
+
def date
|
122
|
+
self.at_beginning_of_day
|
123
|
+
end
|
124
|
+
|
125
|
+
# index number of this day, from Time.at(0) + utc_offset
|
126
|
+
def day_number
|
127
|
+
(self.to_i+self.utc_offset) / 86400
|
128
|
+
end
|
129
|
+
|
130
|
+
# index number of this utc day
|
131
|
+
def day_number_utc
|
132
|
+
self.to_i / 86400
|
133
|
+
end
|
134
|
+
|
135
|
+
# the last microsecond of the day
|
136
|
+
def day_end
|
137
|
+
self.at_beginning_of_day + 86399.999999
|
138
|
+
end
|
139
|
+
|
140
|
+
def date_numeric
|
141
|
+
self.strftime('%Y%m%d')
|
142
|
+
end
|
143
|
+
|
144
|
+
# create a new Time from eg. "20081231"
|
145
|
+
def self.from_date_numeric(aString)
|
146
|
+
local(aString[0,4].to_i,aString[4,2].to_i,aString[6,2].to_i)
|
147
|
+
end
|
148
|
+
|
149
|
+
def time_numeric
|
150
|
+
self.strftime('%H%M%S')
|
151
|
+
end
|
152
|
+
|
153
|
+
def datetime_numeric
|
154
|
+
self.strftime('%Y%m%d-%H%M%S')
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_sql
|
158
|
+
self.strftime('%Y-%m-%d %H:%M:%S')
|
159
|
+
end
|
160
|
+
|
161
|
+
def to_w3c
|
162
|
+
utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
module HashUtils
|
167
|
+
def filter_include!(aKeys,aHash=nil)
|
168
|
+
aHash ||= self
|
169
|
+
|
170
|
+
if aKeys.is_a? Regexp
|
171
|
+
return aHash.delete_if {|k,v| not k =~ aKeys }
|
172
|
+
else
|
173
|
+
aKeys = [aKeys] unless aKeys.is_a? Array
|
174
|
+
return aHash.clear if aKeys.empty?
|
175
|
+
return aHash.delete_if {|key, value| !((aKeys.include?(key)) || (key.is_a?(Symbol) and aKeys.include?(key.to_s)) || (key.is_a?(String) and aKeys.include?(key.to_sym)))}
|
176
|
+
return aHash # last resort
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def filter_include(aKeys,aHash=nil)
|
181
|
+
aHash ||= self
|
182
|
+
filter_include!(aKeys,aHash.clone)
|
183
|
+
end
|
184
|
+
|
185
|
+
def filter_exclude!(aKeys,aHash=nil)
|
186
|
+
aHash ||= self
|
187
|
+
|
188
|
+
if aKeys.is_a? Regexp
|
189
|
+
return aHash.delete_if {|k,v| k =~ aKeys }
|
190
|
+
else
|
191
|
+
aKeys = [aKeys] unless aKeys.is_a? Array
|
192
|
+
return aHash if aKeys.empty?
|
193
|
+
return aHash.delete_if {|key, value| ((aKeys.include?(key)) || (key.is_a?(Symbol) and aKeys.include?(key.to_s)) || (key.is_a?(String) and aKeys.include?(key.to_sym)))}
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def filter_exclude(aKeys,aHash=nil)
|
198
|
+
aHash ||= self
|
199
|
+
filter_exclude!(aKeys,aHash.clone)
|
200
|
+
end
|
201
|
+
|
202
|
+
def has_values_for?(aKeys,aHash=nil)
|
203
|
+
aHash ||= self
|
204
|
+
# check all keys exist in aHash and their values are not nil
|
205
|
+
aKeys.all? { |k,v| aHash[k] }
|
206
|
+
end
|
207
|
+
|
208
|
+
# give a block to execute without the given key in this hash
|
209
|
+
# It will be replaced after the block (guaranteed by ensure)
|
210
|
+
# eg.
|
211
|
+
# hash.without_key(:blah) do |aHash|
|
212
|
+
# puts aHash.inspect
|
213
|
+
# end
|
214
|
+
def without_key(aKey)
|
215
|
+
temp = nil
|
216
|
+
h = self
|
217
|
+
begin
|
218
|
+
if h.include?(aKey)
|
219
|
+
temp = [aKey,h.delete(aKey)]
|
220
|
+
end
|
221
|
+
result = yield(h)
|
222
|
+
ensure
|
223
|
+
h[temp[0]] = temp[1] if temp
|
224
|
+
end
|
225
|
+
return result
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
Hash.class_eval do
|
231
|
+
include HashUtils
|
232
|
+
end
|
233
|
+
|
234
|
+
if defined? HashWithIndifferentAccess
|
235
|
+
HashWithIndifferentAccess.class_eval do
|
236
|
+
include HashUtils
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
module ArrayUtils
|
241
|
+
def filter_include!(aValues,aArray=nil)
|
242
|
+
aArray ||= self
|
243
|
+
if aValues.is_a? Array
|
244
|
+
return aArray if aValues.empty?
|
245
|
+
return aArray.delete_if {|v| not aValues.include? v }
|
246
|
+
elsif aValues.is_a? Regexp
|
247
|
+
return aArray.delete_if {|v| not v =~ aValues }
|
248
|
+
else
|
249
|
+
return filter_include!([aValues],aArray)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def filter_include(aValues,aArray=nil)
|
254
|
+
aArray ||= self
|
255
|
+
filter_include!(aValues,aArray.clone)
|
256
|
+
end
|
257
|
+
|
258
|
+
def filter_exclude!(aValues,aArray=nil)
|
259
|
+
aArray ||= self
|
260
|
+
if aValues.is_a? Array
|
261
|
+
return aArray if aValues.empty?
|
262
|
+
return aArray.delete_if {|v| aValues.include? v }
|
263
|
+
elsif aValues.is_a? Regexp
|
264
|
+
return aArray.delete_if {|v| v =~ aValues }
|
265
|
+
else
|
266
|
+
return filter_exclude!([aValues],aArray)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def filter_exclude(aValues,aArray=nil)
|
271
|
+
aArray ||= self
|
272
|
+
filter_exclude!(aValues,aArray.clone)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
Array.class_eval do
|
277
|
+
include ArrayUtils
|
278
|
+
|
279
|
+
# fixes a memory leak in shift in Ruby 1.8 - should be fixed in 1.9
|
280
|
+
# see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/216055
|
281
|
+
def shift()
|
282
|
+
delete_at(0)
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
Kernel.class_eval do
|
288
|
+
def is_windows?
|
289
|
+
RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
if defined? ActiveRecord
|
294
|
+
ActiveRecord::Base.class_eval do
|
295
|
+
|
296
|
+
def self.find_any_id(aId)
|
297
|
+
with_exclusive_scope { find(:first, {:conditions => {:id => aId}}) }
|
298
|
+
end
|
299
|
+
|
300
|
+
def self.find_any_all(aOptions={})
|
301
|
+
with_exclusive_scope { find(:all, aOptions) }
|
302
|
+
end
|
303
|
+
|
304
|
+
def self.find_ids(aIds)
|
305
|
+
find(:all, {:conditions=> ["id in (?)",aIds.join(',')]})
|
306
|
+
end
|
307
|
+
|
308
|
+
def self.find_any_ids(aIds)
|
309
|
+
with_exclusive_scope { find(:all, {:conditions=> ["id in (?)",aIds.join(',')]}) }
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
end
|