mongoose 0.2.0 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README +13 -10
- data/bin/mongoose_export.rb +17 -0
- data/bin/mongoose_import.rb +17 -0
- data/changes.txt +24 -0
- data/example/simple_examples.rb +63 -26
- data/lib/mongoose.rb +43 -3
- data/lib/mongoose/column.rb +147 -64
- data/lib/mongoose/error.rb +9 -0
- data/lib/mongoose/query.rb +52 -0
- data/lib/mongoose/table.rb +318 -97
- data/lib/mongoose/util.rb +21 -8
- data/test/tc_relations.rb +28 -1
- data/test/tc_table.rb +145 -25
- metadata +9 -4
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Mongoose 0.2.
|
1
|
+
= Mongoose 0.2.5
|
2
2
|
|
3
3
|
A database management system written in Ruby. It has an ActiveRecord-like
|
4
4
|
interface, uses Skiplists for its indexing, and Marshal for its data
|
@@ -15,6 +15,8 @@ provided much of the inspiration for the query language. Also, Ezra has
|
|
15
15
|
graciously taken the time to give me pointers on how to make Mongoose's query
|
16
16
|
language and api better.
|
17
17
|
|
18
|
+
Thanks to everyone who has given me feedback so far on Mongoose.
|
19
|
+
|
18
20
|
Thanks to everyone who gave me feedback on KirbyBase. I have tried to put all
|
19
21
|
the lessons learned from developing that library to good use here.
|
20
22
|
|
@@ -64,7 +66,7 @@ db.create_table(:plane) do |tbl|
|
|
64
66
|
tbl.add_column(:range, :integer)
|
65
67
|
end
|
66
68
|
|
67
|
-
# Add a record.
|
69
|
+
# Add a record. You can also use #create.
|
68
70
|
rec = Plane.new
|
69
71
|
rec.name = 'P-51'
|
70
72
|
rec.country = 'USA'
|
@@ -75,18 +77,18 @@ rec.save
|
|
75
77
|
# Various ways to find a record; should be familiar to ActiveRecord users.
|
76
78
|
Plane.find(1) # Find record with id equal 1.
|
77
79
|
|
78
|
-
Plane.find { speed > 350 } # Find all planes with speed > 350.
|
80
|
+
Plane.find { |plane| plane.speed > 350 } # Find all planes with speed > 350.
|
79
81
|
|
80
82
|
Plane.find # Find all records.
|
81
83
|
|
82
|
-
Plane.find(:first) { country == 'USA' } # Find first plane from USA.
|
84
|
+
Plane.find(:first) { |plane| plane.country == 'USA' } # Find first plane from USA.
|
83
85
|
|
84
|
-
Plane.find do
|
85
|
-
any do
|
86
|
-
country == 'USA'
|
87
|
-
country == 'Great Britain'
|
86
|
+
Plane.find do |plane| # Find all planes from either USA or
|
87
|
+
plane.any do # Great Britain with speed > 400.
|
88
|
+
plane.country == 'USA'
|
89
|
+
plane.country == 'Great Britain'
|
88
90
|
end
|
89
|
-
speed > 400
|
91
|
+
plane.speed > 400
|
90
92
|
end
|
91
93
|
|
92
94
|
# Delete a record.
|
@@ -101,7 +103,8 @@ db.close
|
|
101
103
|
* README - this file
|
102
104
|
* install.rb - install script
|
103
105
|
* changes.txt - history of changes.
|
104
|
-
* lib directory - dbms module
|
106
|
+
* lib directory - dbms module
|
107
|
+
* bin directory - import, export scripts
|
105
108
|
* test directory - unit tests
|
106
109
|
* examples directory - many example scripts demonstrating features.
|
107
110
|
* images directory - images used in manual.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require_gem 'Mongoose'
|
4
|
+
rescue LoadError
|
5
|
+
require 'mongoose'
|
6
|
+
end
|
7
|
+
|
8
|
+
raise "Must supply class name to export!" unless ARGV.size > 0
|
9
|
+
|
10
|
+
class_name = ARGV[0]
|
11
|
+
filename = 1
|
12
|
+
filename = ARGV[1] if ARGV.size > 1
|
13
|
+
|
14
|
+
Object.const_set(ARGV[0], Class.new(Mongoose::Table))
|
15
|
+
|
16
|
+
db = Mongoose::Database.new
|
17
|
+
Object.const_get(class_name).export(filename)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require_gem 'Mongoose'
|
4
|
+
rescue LoadError
|
5
|
+
require 'mongoose'
|
6
|
+
end
|
7
|
+
|
8
|
+
raise "Must supply class name to import!" unless ARGV.size > 0
|
9
|
+
|
10
|
+
class_name = ARGV[0]
|
11
|
+
filename = 0
|
12
|
+
filename = ARGV[1] if ARGV.size > 1
|
13
|
+
|
14
|
+
Object.const_set(ARGV[0], Class.new(Mongoose::Table))
|
15
|
+
|
16
|
+
db = Mongoose::Database.new
|
17
|
+
Object.const_get(class_name).import(filename)
|
data/changes.txt
CHANGED
@@ -23,3 +23,27 @@
|
|
23
23
|
eliminated the string eval. Thanks Logan!
|
24
24
|
* Included a new example from Daniel Sheppard that shows how to integrate
|
25
25
|
ActiveRecord validations into Mongoose.
|
26
|
+
|
27
|
+
2006-07-25:: Version 0.2.5
|
28
|
+
* Logan Capaldo submitted a patch to the Util module to make pluralization
|
29
|
+
a lot smarter. He also added method Table.plural_form. And he updated the
|
30
|
+
test cases to test these changes. Thanks Logan!
|
31
|
+
* Refactored the query engine code. Thanks to Logan Capaldo for code and ideas
|
32
|
+
to get me going.
|
33
|
+
* John Long brought up a great point about losing access to instance variables
|
34
|
+
from the calling object, using the present scheme of #instance_eval(&block)
|
35
|
+
in Table.find. Therefore, I am going back to requiring that the table class
|
36
|
+
be passed as a block parameter and that column names be qualified by the
|
37
|
+
table's class name.
|
38
|
+
* Added Table.import, Table.export methods.
|
39
|
+
* Added Table.destroy, Table.destroy_all, Table.content_columns, Table.exists?
|
40
|
+
methods.
|
41
|
+
* Major cleanup of Table.find. First, I have split the functionality up into
|
42
|
+
separate methods. Second, I believe I have got all of the basic options
|
43
|
+
working: :first, :all, one id, mulitple ids, :order, :limit, :offset.
|
44
|
+
* Added dynamic attribute-base finder methods, i.e. Plane.find_by_country and
|
45
|
+
Plane.find_all_by_country.
|
46
|
+
* Fixed Plane.initialize so that it does the right thing, i.e. if you pass it a
|
47
|
+
hash, it will create a new record initialized to those values.
|
48
|
+
* Added Table#update_attributes method.
|
49
|
+
* Added Table#delete , Table#delete_all methods.
|
data/example/simple_examples.rb
CHANGED
@@ -12,6 +12,7 @@ unless ARGV[0] == 'keep-data'
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
# Create the table class.
|
15
16
|
class Plane < Mongoose::Table
|
16
17
|
validates_presence_of :name, :speed
|
17
18
|
end
|
@@ -30,12 +31,13 @@ unless ARGV[0] == 'keep-data'
|
|
30
31
|
|
31
32
|
# Add records.
|
32
33
|
Plane.create :name => 'P-51', :country => 'USA', :speed => 402, :range => 1205
|
33
|
-
Plane.create :name => 'Spitfire', :country => 'Great Britain', :speed =>
|
34
|
+
Plane.create :name => 'Spitfire', :country => 'Great Britain', :speed => 351,
|
34
35
|
:range => 454
|
35
36
|
Plane.create :name => 'ME-109', :country => 'Germany', :speed => 354,
|
36
37
|
:range => 501
|
37
38
|
|
38
|
-
# Forgot value for speed, which is a required field.
|
39
|
+
# Forgot value for speed, which is a required field. Notice
|
40
|
+
# validates_presence_of in the class definition above.
|
39
41
|
begin
|
40
42
|
Plane.create :name => 'P-39', :country => 'USA', :range => 701
|
41
43
|
rescue RuntimeError => e
|
@@ -49,52 +51,87 @@ puts "\n\nFind P-51 record by ID"
|
|
49
51
|
p_51 = Plane.find(1)
|
50
52
|
p p_51
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
p_51.save
|
56
|
-
end
|
54
|
+
# Change speed on P-51 record and save.
|
55
|
+
p_51.speed = 405
|
56
|
+
p_51.save
|
57
57
|
|
58
58
|
puts "\n\nFind all records with speed greater than 350 mph"
|
59
|
-
result = Plane.find { speed > 350 }
|
59
|
+
result = Plane.find { |plane| plane.speed > 350 }
|
60
60
|
p result
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
|
63
|
+
puts "\n\nFind all US planes with speed greater than 350 mph"
|
64
|
+
result = Plane.find { |plane| plane.country == 'USA' and plane.speed > 350 }
|
64
65
|
p result
|
65
66
|
|
66
67
|
puts "\n\nFind all British planes with speed greater than 300 mph"
|
67
|
-
result = Plane.find do
|
68
|
-
country == 'Great Britain' and speed > 300
|
68
|
+
result = Plane.find do |plane|
|
69
|
+
plane.country == 'Great Britain' and plane.speed > 300
|
69
70
|
end
|
70
71
|
p result
|
71
72
|
|
72
73
|
puts "\n\nFind all Allied planes"
|
73
|
-
result = Plane.find do
|
74
|
-
any do
|
75
|
-
country == 'USA'
|
76
|
-
country == 'Great Britain'
|
74
|
+
result = Plane.find do |plane|
|
75
|
+
plane.any do
|
76
|
+
plane.country == 'USA'
|
77
|
+
plane.country == 'Great Britain'
|
77
78
|
end
|
78
79
|
end
|
79
80
|
p result
|
80
81
|
|
81
|
-
puts "\n\nFind all Allied planes with speed greater than
|
82
|
-
result = Plane.find do
|
83
|
-
any do
|
84
|
-
country == 'USA'
|
85
|
-
country == 'Great Britain'
|
82
|
+
puts "\n\nFind all Allied planes with speed greater than 350 mph"
|
83
|
+
result = Plane.find do |plane|
|
84
|
+
plane.any do
|
85
|
+
plane.country == 'USA'
|
86
|
+
plane.country == 'Great Britain'
|
86
87
|
end
|
87
|
-
speed >
|
88
|
+
plane.speed > 350
|
88
89
|
end
|
89
90
|
p result
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
92
|
+
puts "\n\nFind all Allied planes with speed between 300 and 350 mph"
|
93
|
+
result = Plane.find do |plane|
|
94
|
+
plane.any do
|
95
|
+
plane.country == 'USA'
|
96
|
+
plane.country == 'Great Britain'
|
97
|
+
end
|
98
|
+
plane.speed.between(300, 350)
|
99
|
+
end
|
100
|
+
p result
|
95
101
|
|
96
102
|
puts "\n\nFind all records in table."
|
97
103
|
result = Plane.find
|
98
104
|
p result
|
99
105
|
|
106
|
+
puts "\n\nFind by dynamic finder method."
|
107
|
+
result = Plane.find_by_name('ME-109')
|
108
|
+
p result
|
109
|
+
|
110
|
+
puts "\n\nSort result set by name."
|
111
|
+
result = Plane.find(:all, :order => :name)
|
112
|
+
p result
|
113
|
+
|
114
|
+
puts "\n\nSort by country, then name."
|
115
|
+
result = Plane.find(:order => [:country, :name])
|
116
|
+
p result
|
117
|
+
|
118
|
+
puts "\n\nSort by speed descending."
|
119
|
+
result = Plane.find(:order => -:speed)
|
120
|
+
p result
|
121
|
+
|
122
|
+
puts "\n\nLimit number of records returned."
|
123
|
+
result = Plane.find(:order => :name, :limit => 2)
|
124
|
+
p result
|
125
|
+
|
126
|
+
puts "\n\nSpecify offset."
|
127
|
+
result = Plane.find(:order => :name, :offset => 3)
|
128
|
+
p result
|
129
|
+
|
130
|
+
# Delete Spitfire record.
|
131
|
+
spitfire = Plane.find(:first) { |plane| plane.name == 'Spitfire' }
|
132
|
+
spitfire.destroy if spitfire
|
133
|
+
|
134
|
+
puts "\n\nShow only content columns."
|
135
|
+
Plane.content_columns.each { |c| puts c.name }
|
136
|
+
|
100
137
|
db.close
|
data/lib/mongoose.rb
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'pp'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'time'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'faster_csv'
|
9
|
+
rescue LoadError
|
10
|
+
require 'csv'
|
11
|
+
end
|
12
|
+
|
2
13
|
require 'mongoose/database'
|
3
14
|
require 'mongoose/table'
|
4
15
|
require 'mongoose/column'
|
5
16
|
require 'mongoose/skiplist'
|
6
17
|
require 'mongoose/linear_search'
|
18
|
+
require 'mongoose/query'
|
7
19
|
require 'mongoose/util'
|
20
|
+
require 'mongoose/error'
|
8
21
|
|
9
22
|
#
|
10
23
|
# :main:Mongoose
|
@@ -22,7 +35,7 @@ require 'mongoose/util'
|
|
22
35
|
#
|
23
36
|
module Mongoose
|
24
37
|
|
25
|
-
VERSION = '0.2.
|
38
|
+
VERSION = '0.2.5'
|
26
39
|
DATA_TYPES = [:string, :integer, :float, :time, :date, :datetime, :boolean]
|
27
40
|
TBL_EXT = '.mgt'
|
28
41
|
TBL_HDR_EXT = '.mgh'
|
@@ -30,14 +43,41 @@ TBL_IDX_EXT = '.mgi'
|
|
30
43
|
|
31
44
|
end
|
32
45
|
|
33
|
-
|
46
|
+
|
47
|
+
#-------------------------------------------------------------------------------
|
34
48
|
# Object
|
35
|
-
|
49
|
+
#-------------------------------------------------------------------------------
|
36
50
|
class Object
|
37
51
|
def full_const_get(name)
|
38
52
|
list = name.split("::")
|
39
53
|
obj = Object
|
40
54
|
list.each {|x| obj = obj.const_get(x) }
|
41
55
|
obj
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
#-------------------------------------------------------------------------------
|
61
|
+
# Symbol
|
62
|
+
#-------------------------------------------------------------------------------
|
63
|
+
class Symbol
|
64
|
+
#-----------------------------------------------------------------------------
|
65
|
+
# -@
|
66
|
+
#-----------------------------------------------------------------------------
|
67
|
+
#
|
68
|
+
# This allows you to put a minus sign in front of a field name in order
|
69
|
+
# to specify descending sort order.
|
70
|
+
def -@
|
71
|
+
("-"+self.to_s).to_sym
|
72
|
+
end
|
73
|
+
|
74
|
+
#-----------------------------------------------------------------------------
|
75
|
+
# +@
|
76
|
+
#-----------------------------------------------------------------------------
|
77
|
+
#
|
78
|
+
# This allows you to put a plus sign in front of a field name in order
|
79
|
+
# to specify ascending sort order.
|
80
|
+
def +@
|
81
|
+
("+"+self.to_s).to_sym
|
42
82
|
end
|
43
83
|
end
|
data/lib/mongoose/column.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
1
|
module Mongoose
|
4
2
|
|
5
3
|
#-------------------------------------------------------------------------------
|
@@ -11,14 +9,32 @@ class BaseColumn
|
|
11
9
|
|
12
10
|
private_class_method :new
|
13
11
|
|
12
|
+
extend Forwardable
|
13
|
+
def_delegator(:@idx, :>, :>)
|
14
|
+
def_delegator(:@idx, :>=, :>=)
|
15
|
+
def_delegator(:@idx, :==, :==)
|
16
|
+
def_delegator(:@idx, :<, :<)
|
17
|
+
def_delegator(:@idx, :<=, :<=)
|
18
|
+
def_delegator(:@idx, :between, :between)
|
19
|
+
def_delegator(:@idx, :one_of, :one_of)
|
20
|
+
|
21
|
+
#-----------------------------------------------------------------------
|
22
|
+
# BaseColumn.valid_data_type?
|
23
|
+
#-----------------------------------------------------------------------
|
14
24
|
def self.valid_data_type?(data_type)
|
15
25
|
DATA_TYPES.include?(data_type)
|
16
26
|
end
|
17
27
|
|
28
|
+
#-----------------------------------------------------------------------
|
29
|
+
# BaseColumn.create_table
|
30
|
+
#-----------------------------------------------------------------------
|
18
31
|
def self.create(tbl_class, name, col_def)
|
19
32
|
return new(tbl_class, name, col_def)
|
20
33
|
end
|
21
34
|
|
35
|
+
#-----------------------------------------------------------------------
|
36
|
+
# initialize
|
37
|
+
#-----------------------------------------------------------------------
|
22
38
|
def initialize(tbl_class, name, col_def)
|
23
39
|
@tbl_class = tbl_class
|
24
40
|
@name = name
|
@@ -27,17 +43,47 @@ class BaseColumn
|
|
27
43
|
@required = false
|
28
44
|
end
|
29
45
|
|
46
|
+
#-----------------------------------------------------------------------
|
47
|
+
# indexed?
|
48
|
+
#-----------------------------------------------------------------------
|
30
49
|
def indexed?
|
31
50
|
@indexed
|
32
51
|
end
|
33
52
|
|
53
|
+
#-----------------------------------------------------------------------
|
54
|
+
# required?
|
55
|
+
#-----------------------------------------------------------------------
|
34
56
|
def required?
|
35
57
|
@required
|
36
58
|
end
|
37
59
|
|
60
|
+
#-----------------------------------------------------------------------
|
61
|
+
# close
|
62
|
+
#-----------------------------------------------------------------------
|
38
63
|
def close
|
39
64
|
end
|
40
65
|
|
66
|
+
#-----------------------------------------------------------------------
|
67
|
+
# convert_to_native
|
68
|
+
#-----------------------------------------------------------------------
|
69
|
+
def convert_to_native(value)
|
70
|
+
case @data_type
|
71
|
+
when :string
|
72
|
+
value.to_s
|
73
|
+
when :integer
|
74
|
+
value.to_i
|
75
|
+
when :float
|
76
|
+
value.to_f
|
77
|
+
when :time
|
78
|
+
Time.parse(value)
|
79
|
+
when :date
|
80
|
+
Date.parse(value)
|
81
|
+
when :datetime
|
82
|
+
DateTime.parse(value)
|
83
|
+
when :boolean
|
84
|
+
true if [true, 'true', 1].include?(value)
|
85
|
+
end
|
86
|
+
end
|
41
87
|
end
|
42
88
|
|
43
89
|
|
@@ -45,38 +91,13 @@ end
|
|
45
91
|
# Column class
|
46
92
|
#-------------------------------------------------------------------------------
|
47
93
|
class Column < BaseColumn
|
94
|
+
#-----------------------------------------------------------------------
|
95
|
+
# initialize
|
96
|
+
#-----------------------------------------------------------------------
|
48
97
|
def initialize(tbl_class, name, col_def)
|
49
98
|
super
|
50
99
|
@idx = LinearSearch.new(self)
|
51
100
|
end
|
52
|
-
|
53
|
-
def >(other)
|
54
|
-
@tbl_class.query << [@idx, :>, other]
|
55
|
-
end
|
56
|
-
|
57
|
-
def >=(other)
|
58
|
-
@tbl_class.query << [@idx, :>=, other]
|
59
|
-
end
|
60
|
-
|
61
|
-
def <(other)
|
62
|
-
@tbl_class.query << [@idx, :<, other]
|
63
|
-
end
|
64
|
-
|
65
|
-
def <=(other)
|
66
|
-
@tbl_class.query << [@idx, :<=, other]
|
67
|
-
end
|
68
|
-
|
69
|
-
def ==(other)
|
70
|
-
@tbl_class.query << [@idx, :==, other]
|
71
|
-
end
|
72
|
-
|
73
|
-
def between(*other)
|
74
|
-
@tbl_class.query << [@idx, :between, other]
|
75
|
-
end
|
76
|
-
|
77
|
-
def one_of(*other)
|
78
|
-
@tbl_class.query << [@idx, :one_of, other]
|
79
|
-
end
|
80
101
|
end
|
81
102
|
|
82
103
|
|
@@ -145,51 +166,31 @@ end
|
|
145
166
|
# SkipListIndexColumn class
|
146
167
|
#-------------------------------------------------------------------------------
|
147
168
|
class SkipListIndexColumn < IndexedColumn
|
169
|
+
#-----------------------------------------------------------------------
|
170
|
+
# initialize
|
171
|
+
#-----------------------------------------------------------------------
|
148
172
|
def initialize(tbl_class, name, col_def)
|
149
173
|
@idx = SkipList.new(self)
|
150
174
|
super
|
151
175
|
end
|
152
176
|
|
177
|
+
#-----------------------------------------------------------------------
|
178
|
+
# clear_index
|
179
|
+
#-----------------------------------------------------------------------
|
153
180
|
def clear_index
|
154
181
|
@idx = SkipList.new(self)
|
155
182
|
end
|
156
183
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
def >=(other)
|
162
|
-
@tbl_class.query << [@idx, :>=, other]
|
163
|
-
end
|
164
|
-
|
165
|
-
def <(other)
|
166
|
-
@tbl_class.query << [@idx, :<, other]
|
167
|
-
end
|
168
|
-
|
169
|
-
def <=(other)
|
170
|
-
@tbl_class.query << [@idx, :<=, other]
|
171
|
-
end
|
172
|
-
|
173
|
-
def ==(other)
|
174
|
-
@tbl_class.query << [@idx, :==, other]
|
175
|
-
end
|
176
|
-
|
177
|
-
def search(other)
|
178
|
-
@tbl_class.query << [@idx, :search, other]
|
179
|
-
end
|
180
|
-
|
181
|
-
def between(*other)
|
182
|
-
@tbl_class.query << [@idx, :between, other]
|
183
|
-
end
|
184
|
-
|
185
|
-
def one_of(*other)
|
186
|
-
@tbl_class.query << [@idx, :one_of, other]
|
187
|
-
end
|
188
|
-
|
184
|
+
#-----------------------------------------------------------------------
|
185
|
+
# rebuild_index_file
|
186
|
+
#-----------------------------------------------------------------------
|
189
187
|
def rebuild_index_file
|
190
188
|
with_index_file('w') { |fptr| fptr.write(Marshal.dump(@idx.dump_to_hash)) }
|
191
189
|
end
|
192
190
|
|
191
|
+
#-----------------------------------------------------------------------
|
192
|
+
# rebuild_index_from_table
|
193
|
+
#-----------------------------------------------------------------------
|
193
194
|
def rebuild_index_from_table
|
194
195
|
clear_index
|
195
196
|
i = @tbl_class.columns.index(self)
|
@@ -199,15 +200,24 @@ class SkipListIndexColumn < IndexedColumn
|
|
199
200
|
end
|
200
201
|
end
|
201
202
|
|
203
|
+
#-----------------------------------------------------------------------
|
204
|
+
# rebuild_index_from_index_file
|
205
|
+
#-----------------------------------------------------------------------
|
202
206
|
def rebuild_index_from_index_file
|
203
207
|
clear_index
|
204
208
|
with_index_file { |fptr| @idx.load_from_hash(Marshal.load(fptr)) }
|
205
209
|
end
|
206
210
|
|
211
|
+
#-----------------------------------------------------------------------
|
212
|
+
# add_index_rec
|
213
|
+
#-----------------------------------------------------------------------
|
207
214
|
def add_index_rec(key, value)
|
208
215
|
@idx.store(key, value)
|
209
216
|
end
|
210
217
|
|
218
|
+
#-----------------------------------------------------------------------
|
219
|
+
# remove_index_rec
|
220
|
+
#-----------------------------------------------------------------------
|
211
221
|
def remove_index_rec(key, value)
|
212
222
|
@idx.remove(key, value)
|
213
223
|
end
|
@@ -218,38 +228,111 @@ end
|
|
218
228
|
# IDColumn class
|
219
229
|
#-------------------------------------------------------------------------------
|
220
230
|
class IDColumn < IndexedColumn
|
221
|
-
|
222
|
-
|
231
|
+
def_delegator(:@idx, :==, :[])
|
223
232
|
def_delegator(:@idx, :[], :[])
|
224
233
|
def_delegator(:@idx, :keys, :keys)
|
225
234
|
|
235
|
+
#-----------------------------------------------------------------------
|
236
|
+
# initialize
|
237
|
+
#-----------------------------------------------------------------------
|
226
238
|
def initialize(tbl_class, name, col_def)
|
227
239
|
@idx = {}
|
228
240
|
super
|
229
241
|
end
|
230
242
|
|
243
|
+
#-----------------------------------------------------------------------
|
244
|
+
# clear_index
|
245
|
+
#-----------------------------------------------------------------------
|
231
246
|
def clear_index
|
232
247
|
@idx = {}
|
233
248
|
end
|
234
249
|
|
250
|
+
#-----------------------------------------------------------------------
|
251
|
+
# >
|
252
|
+
#-----------------------------------------------------------------------
|
253
|
+
def >(other)
|
254
|
+
return @idx.keys.select { |k| k > other }
|
255
|
+
end
|
256
|
+
|
257
|
+
#-----------------------------------------------------------------------
|
258
|
+
# >=
|
259
|
+
#-----------------------------------------------------------------------
|
260
|
+
def >=(other)
|
261
|
+
return @idx.keys.select { |k| k >= other }
|
262
|
+
end
|
263
|
+
|
264
|
+
#-----------------------------------------------------------------------
|
265
|
+
# <
|
266
|
+
#-----------------------------------------------------------------------
|
267
|
+
def <(other)
|
268
|
+
return @idx.keys.select { |k| k < other }
|
269
|
+
end
|
270
|
+
|
271
|
+
#-----------------------------------------------------------------------
|
272
|
+
# <=
|
273
|
+
#-----------------------------------------------------------------------
|
274
|
+
def <=(other)
|
275
|
+
return @idx.keys.select { |k| k <= other }
|
276
|
+
end
|
277
|
+
|
278
|
+
#-----------------------------------------------------------------------
|
279
|
+
# between
|
280
|
+
#-----------------------------------------------------------------------
|
281
|
+
def between(search_start, search_end, start_inclusive=false,
|
282
|
+
end_inclusive=false)
|
283
|
+
return @idx.keys.select do |k|
|
284
|
+
if k == search_start and start_inclusive
|
285
|
+
true
|
286
|
+
elsif k > search_start and k < search_end
|
287
|
+
true
|
288
|
+
elsif k == search_end and end_inclusive
|
289
|
+
true
|
290
|
+
else
|
291
|
+
false
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
#-----------------------------------------------------------------------
|
297
|
+
# one_of
|
298
|
+
#-----------------------------------------------------------------------
|
299
|
+
def one_of(*other)
|
300
|
+
return @idx.keys.select { |k| other.include?(k) }
|
301
|
+
end
|
302
|
+
|
303
|
+
#-----------------------------------------------------------------------
|
304
|
+
# rebuild_index_file
|
305
|
+
#-----------------------------------------------------------------------
|
235
306
|
def rebuild_index_file
|
236
307
|
with_index_file('w') { |fptr| fptr.write(Marshal.dump(@idx)) }
|
237
308
|
end
|
238
309
|
|
310
|
+
#-----------------------------------------------------------------------
|
311
|
+
# rebuild_index_from_table
|
312
|
+
#-----------------------------------------------------------------------
|
239
313
|
def rebuild_index_from_table
|
240
314
|
clear_index
|
241
315
|
@tbl_class.get_all_recs { |rec, fpos| add_index_rec(rec[0], fpos) }
|
242
316
|
end
|
243
317
|
|
318
|
+
#-----------------------------------------------------------------------
|
319
|
+
# rebuild_index_from_index_file
|
320
|
+
#-----------------------------------------------------------------------
|
244
321
|
def rebuild_index_from_index_file
|
245
322
|
clear_index
|
246
323
|
with_index_file { |fptr| @idx = Marshal.load(fptr) }
|
247
324
|
end
|
248
325
|
|
326
|
+
#-----------------------------------------------------------------------
|
327
|
+
# add_index_rec
|
328
|
+
#-----------------------------------------------------------------------
|
249
329
|
def add_index_rec(id, fpos)
|
250
330
|
@idx[id] = fpos
|
251
331
|
end
|
252
332
|
|
333
|
+
#-----------------------------------------------------------------------
|
334
|
+
# remove_index_rec
|
335
|
+
#-----------------------------------------------------------------------
|
253
336
|
def remove_index_rec(id)
|
254
337
|
@idx.delete(id)
|
255
338
|
end
|