KirbyBase 2.5.2 → 2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README +2 -8
- data/changes.txt +15 -0
- data/examples/aaa_try_this_first/kbtest.rb +32 -0
- data/examples/indexes_test/index_test.rb +28 -5
- data/examples/record_class_test/record_class_test2.rb +38 -0
- data/examples/yaml_field_test/yaml_field_test.rb +1 -1
- data/kirbybaserubymanual.html +66 -15
- data/lib/kirbybase.rb +185 -93
- data/test/tc_local_db.rb +1 -1
- data/test/tc_local_table.rb +33 -0
- metadata +111 -108
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= KirbyBase 2.
|
1
|
+
= KirbyBase 2.6
|
2
2
|
|
3
3
|
A small, plain-text, dbms written in Ruby. It can be used either embedded
|
4
4
|
or client/server.
|
@@ -31,12 +31,6 @@ See the examples directory for examples of how to use KirbyBase.
|
|
31
31
|
* images directory - images used in manual.
|
32
32
|
|
33
33
|
|
34
|
-
== Warning
|
35
|
-
|
36
|
-
KirbyBase defines #method_missing for NilClass. This might bite you in the
|
37
|
-
butt if you override NilClass.method_missing yourself.
|
38
|
-
|
39
|
-
|
40
34
|
== Author
|
41
35
|
|
42
36
|
Written in 2005 by Jamey Cribbs <mailto:jcribbs@twmi.rr.com>
|
@@ -66,7 +60,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
66
60
|
Please send any bug reports, suggestions, ideas,
|
67
61
|
improvements, to:
|
68
62
|
|
69
|
-
jcribbs@
|
63
|
+
jcribbs@netpromi.com
|
70
64
|
|
71
65
|
== Home Page
|
72
66
|
|
data/changes.txt
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
2006-06-27:: Version 2.6
|
2
|
+
* Removed NilClass#method_missing. I have replaced it with a new class
|
3
|
+
called KBNilClass. Thanks to a host of people for help on this,
|
4
|
+
including: Assaph Mehr, James Edward Gray II, Matthew Desmarais,
|
5
|
+
Logan Capaldo, Trans, John Carter, Dave Burt and anyone else I missed.
|
6
|
+
* Added conditional require logic so that KirbyBase will use FasterCVS if
|
7
|
+
it is available. Thanks to James Edward Gray II for this.
|
8
|
+
* You can now delay index creation in local mode. Thanks to Nicholas Rahn
|
9
|
+
for this.
|
10
|
+
* Added ability to allow for a custom record class with no kb_create or
|
11
|
+
kb_defaults methods. KirbyBase will return each result record as an
|
12
|
+
instance of the custom record class, and will attempt to set attributes
|
13
|
+
with the same names as the table's field names equal to the values of
|
14
|
+
the table record's fields. Thanks to Hal Fulton for this idea.
|
15
|
+
|
1
16
|
2005-12-30:: Version 2.5.2
|
2
17
|
* Changed the behavior of KBTable#insert method. If user specifies nil
|
3
18
|
for a field value and there is a default value for that field, the
|
@@ -83,6 +83,7 @@ plane_tbl.insert('P-39', 'USA', 'Fighter', nil, nil,
|
|
83
83
|
nil, false)
|
84
84
|
plane_tbl.insert('Zero', 'Japan', 'Fighter', 377, 912,
|
85
85
|
Date.new(1937,5,15), true)
|
86
|
+
plane_tbl.insert('B-25', 'USA', '', 320, 1340, Date.new(1940,4,4), true)
|
86
87
|
|
87
88
|
#--------------------- Update Examples -------------------------------------
|
88
89
|
# Four different ways to update existing data in KirbyBase. In all three
|
@@ -195,6 +196,37 @@ puts plane_tbl.select { |r|
|
|
195
196
|
r.country == plane_tbl.select { |x| x.name == 'Zero' }.first.country
|
196
197
|
}
|
197
198
|
|
199
|
+
#-------------------------- Select Example 11 -------------------------------
|
200
|
+
print_divider('Select Example 11')
|
201
|
+
# Select all planes.
|
202
|
+
plane_tbl.select.each { |r| puts r }
|
203
|
+
|
204
|
+
#-------------------------- Select Example 12 -------------------------------
|
205
|
+
print_divider('Select Example 12')
|
206
|
+
# Select all planes with a speed of nil.
|
207
|
+
|
208
|
+
#**************** Note: This example also demonstrates the change from
|
209
|
+
# nil to kb_nil for KirbyBase's internal representation of a nil value. You
|
210
|
+
# should only encounter this different if you have to check for nil in your
|
211
|
+
# query, as this example does. Other than that, everything else should
|
212
|
+
# be transparent, since KirbyBase converts a kb_nil back into a nil when it
|
213
|
+
# returns a query's result set.
|
214
|
+
#***************
|
215
|
+
plane_tbl.select { |r| r.speed.kb_nil? }.each { |r| puts r }
|
216
|
+
|
217
|
+
#-------------------------- Select Example 13 -------------------------------
|
218
|
+
print_divider('Select Example 13')
|
219
|
+
# Same thing, but in a slightly different way.
|
220
|
+
|
221
|
+
#**************** Note: This example also demonstrates the change from
|
222
|
+
# nil to kb_nil for KirbyBase's internal representation of a nil value. You
|
223
|
+
# should only encounter this different if you have to check for nil in your
|
224
|
+
# query, as this example does. Other than that, everything else should
|
225
|
+
# be transparent, since KirbyBase converts a kb_nil back into a nil when it
|
226
|
+
# returns a query's result set.
|
227
|
+
#***************
|
228
|
+
plane_tbl.select { |r| r.speed == kb_nil }.each { |r| puts r }
|
229
|
+
|
198
230
|
#-------------------------- Misc. Methods Examples -------------------------
|
199
231
|
print_divider('Misc. Methods Examples')
|
200
232
|
puts 'Total # of records in table: %d' % plane_tbl.total_recs
|
@@ -37,18 +37,23 @@ address_book_tbl = db.create_table(:address_book,
|
|
37
37
|
:street_address, :String,
|
38
38
|
:city, :String,
|
39
39
|
:phone, :String,
|
40
|
-
:category, {:DataType=>:String, :Index=>2}
|
40
|
+
:category, {:DataType=>:String, :Index=>2},
|
41
|
+
:age, {:DataType=>:Integer, :Index=>3}
|
41
42
|
)
|
42
43
|
|
43
44
|
# Insert some contact info records.
|
44
45
|
address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave', 'Gotham City',
|
45
|
-
'111-111-1111', 'Super Hero')
|
46
|
+
'111-111-1111', 'Super Hero', 39)
|
46
47
|
address_book_tbl.insert('Bugs', 'Bunny', '1234 Rabbit Hole', 'The Forest',
|
47
|
-
'222-222-2222', 'Cartoon Character')
|
48
|
+
'222-222-2222', 'Cartoon Character', 12)
|
48
49
|
address_book_tbl.insert('George', 'Bush', '1600 Pennsylvania Ave',
|
49
|
-
'Washington', '333-333-3333', 'President')
|
50
|
+
'Washington', '333-333-3333', 'President', 2)
|
50
51
|
address_book_tbl.insert('Silver', 'Surfer', '1234 Galaxy Way',
|
51
|
-
'Any City', '444-444-4444', 'Super Hero')
|
52
|
+
'Any City', '444-444-4444', 'Super Hero', 199)
|
53
|
+
address_book_tbl.insert('John', 'Doe', '1234 Robin Lane', 'Detroit',
|
54
|
+
'999-999-9999', nil, 54)
|
55
|
+
address_book_tbl.insert(nil, 'NoFirstName', 'Nowhere Road', 'Notown',
|
56
|
+
'000-000-0000', 'Nothing', nil)
|
52
57
|
|
53
58
|
# Select all super heros without using the index.
|
54
59
|
address_book_tbl.select { |r| r.category == 'Super Hero' }.each { |r|
|
@@ -68,4 +73,22 @@ address_book_tbl.select_by_firstname_lastname_index { |r|
|
|
68
73
|
r.firstname == 'Bugs' and r.lastname == 'Bunny'
|
69
74
|
}.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
|
70
75
|
|
76
|
+
puts;puts
|
77
|
+
# Select the guy with no first name using the firstname+lastname index.
|
78
|
+
address_book_tbl.select_by_firstname_lastname_index { |r|
|
79
|
+
r.lastname == 'NoFirstName'
|
80
|
+
}.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
|
81
|
+
|
82
|
+
puts;puts
|
83
|
+
# Select the guy with no first name using the firstname+lastname index.
|
84
|
+
# This time we will explicitly say firstname should be nil
|
85
|
+
address_book_tbl.select_by_firstname_lastname_index { |r|
|
86
|
+
r.firstname.nil? and r.lastname == 'NoFirstName'
|
87
|
+
}.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
|
88
|
+
|
89
|
+
puts;puts
|
90
|
+
address_book_tbl.select_by_age_index { |r| r.age > 30 }.each { |r|
|
91
|
+
puts '%s %s %d' % [r.firstname, r.lastname, r.age] }
|
92
|
+
|
93
|
+
puts;puts
|
71
94
|
p address_book_tbl.field_indexes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#Test of returning result set composed of instances of user class. This
|
2
|
+
#example differs from the first in that there is no kb_create method, so
|
3
|
+
#KirbyBase will default to create a new instance of the record's custom
|
4
|
+
#class and setting each instance attribute to each field's value.
|
5
|
+
|
6
|
+
require 'kirbybase'
|
7
|
+
|
8
|
+
class Foobar
|
9
|
+
attr_accessor(:recno, :name, :country, :role, :speed, :range,
|
10
|
+
:began_service, :still_flying)
|
11
|
+
end
|
12
|
+
|
13
|
+
# To run local, single-user, uncomment next line.
|
14
|
+
db = KirbyBase.new
|
15
|
+
|
16
|
+
# If table exists, delete it.
|
17
|
+
db.drop_table(:plane) if db.table_exists?(:plane)
|
18
|
+
|
19
|
+
# Create a table. Notice how you set record_class equal to your class.
|
20
|
+
plane_tbl = db.create_table do |t|
|
21
|
+
t.name = :plane
|
22
|
+
t.field_defs = [:name, :String, :country, :String, :role, :String,
|
23
|
+
:speed, :Integer, :range, :Integer, :began_service, :Date,
|
24
|
+
:still_flying, :Boolean]
|
25
|
+
t.encrypt = false
|
26
|
+
t.record_class = Foobar
|
27
|
+
end
|
28
|
+
|
29
|
+
plane_tbl = db.get_table(:plane)
|
30
|
+
|
31
|
+
# Insert a record.
|
32
|
+
plane_tbl.insert('Spitfire','Great Britain','Fighter',333,454,
|
33
|
+
Date.new(1936, 1, 1),true)
|
34
|
+
|
35
|
+
# Notice how select returns instances of Foobar, even there is no
|
36
|
+
# kb_create method.
|
37
|
+
recs = plane_tbl.select
|
38
|
+
p recs.first
|
@@ -25,7 +25,7 @@ pet_tbl.insert('Kirby', 'dog', Date.new(2002, 06, 01),
|
|
25
25
|
pet_tbl.insert('Mojo', 'cat', Date.new(2000, 04, 01),
|
26
26
|
['cute', 'soft', '6', 12.25])
|
27
27
|
pet_tbl.insert('Goldy', 'fish', Date.new(2004, 10, 10),
|
28
|
-
|
28
|
+
[])
|
29
29
|
|
30
30
|
pet_tbl.select.each { |r|
|
31
31
|
puts '%s %s' % [r.name, r.characteristics[1]]
|
data/kirbybaserubymanual.html
CHANGED
@@ -261,8 +261,8 @@ div.exampleblock-content {
|
|
261
261
|
<div id="header">
|
262
262
|
<h1>KirbyBase Manual (Ruby Version)</h1>
|
263
263
|
<span id="author">Jamey Cribbs</span><br />
|
264
|
-
<span id="email"><tt><<a href="mailto:jcribbs@
|
265
|
-
v2.
|
264
|
+
<span id="email"><tt><<a href="mailto:jcribbs@netpromi.com">jcribbs@netpromi.com</a>></tt></span><br />
|
265
|
+
v2.6 June 2006
|
266
266
|
</div>
|
267
267
|
<div id="preamble">
|
268
268
|
<div class="sectionbody">
|
@@ -270,7 +270,7 @@ v2.5.2 December 2005
|
|
270
270
|
<div class="content">
|
271
271
|
<img src="images/kirby1.jpg" alt="images/kirby1.jpg"/>
|
272
272
|
</div>
|
273
|
-
<div class="image-title">Figure: Kirby pictured here in attack mode.</div>
|
273
|
+
<div class="image-title">Figure: Kirby, pictured here in attack mode.</div>
|
274
274
|
</div>
|
275
275
|
</div>
|
276
276
|
</div>
|
@@ -386,6 +386,11 @@ v2.5.2 December 2005
|
|
386
386
|
<a href="#selects-involving-lookups-or-link-manys">Selects involving Lookups or Link_manys</a>
|
387
387
|
</p>
|
388
388
|
</li>
|
389
|
+
<li>
|
390
|
+
<p>
|
391
|
+
<a href="#a-note-about-nil-values">A note about nil values</a>
|
392
|
+
</p>
|
393
|
+
</li>
|
389
394
|
</ol>
|
390
395
|
</li>
|
391
396
|
<li>
|
@@ -708,9 +713,10 @@ MySQL.</p>
|
|
708
713
|
<div class="sidebarblock">
|
709
714
|
<div class="sidebar-content">
|
710
715
|
<div class="sidebar-title">Drop me a line!</div>
|
711
|
-
<p>If you find a use for KirbyBase, please send an email
|
712
|
-
|
713
|
-
|
716
|
+
<p>If you find a use for KirbyBase, please send me an email telling how you
|
717
|
+
use it, whether it is ok for me to mention your application on the
|
718
|
+
"KirbyBase Applications" webpage, and possibly a link to your application's
|
719
|
+
webpage (if you have one).</p>
|
714
720
|
</div></div>
|
715
721
|
</div>
|
716
722
|
<h2><a id="connecting-to-a-database"></a>Connecting to a database</h2>
|
@@ -750,14 +756,14 @@ a different extension, pass this as an argument, like so:</p>
|
|
750
756
|
memo/blob files, you need to pass the location as an argument, like so:</p>
|
751
757
|
<div class="listingblock">
|
752
758
|
<div class="content">
|
753
|
-
<pre><tt>db = KirbyBase.new(:local, nil, './', '.tbl', './memos')</tt></pre>
|
759
|
+
<pre><tt>db = KirbyBase.new(:local, nil, nil, './', '.tbl', './memos')</tt></pre>
|
754
760
|
</div></div>
|
755
761
|
<p>If you don't want KirbyBase to spend time initially creating all of the
|
756
762
|
indexes for the tables in the database, you can pass true as the
|
757
763
|
delay_index_creation argument:</p>
|
758
764
|
<div class="listingblock">
|
759
765
|
<div class="content">
|
760
|
-
<pre><tt>db = KirbyBase.new(:local, nil, './', '.tbl', './', true)</tt></pre>
|
766
|
+
<pre><tt>db = KirbyBase.new(:local, nil, nil, './', '.tbl', './', true)</tt></pre>
|
761
767
|
</div></div>
|
762
768
|
<p>KirbyBase will skip initial index creation and will create a table's
|
763
769
|
indexes when the table is first referenced.</p>
|
@@ -828,8 +834,12 @@ end</tt></pre>
|
|
828
834
|
<p>You can also specify that you want records of the table to be returned to
|
829
835
|
you as instances of a class. To do this, simply define a class before you
|
830
836
|
call #create_table. This class needs to have an accessor for each fieldname
|
831
|
-
in the table
|
832
|
-
|
837
|
+
in the table.</p>
|
838
|
+
<p>If this class has a class method, called #kb_create, KirbyBase, when
|
839
|
+
creating each record of the result set, will call that method and pass it
|
840
|
+
the field values of the result record. #kb_create will need to handle
|
841
|
+
creating an instance of the record class itself.</p>
|
842
|
+
<p>Here is an example of #kb_create in action:</p>
|
833
843
|
<div class="listingblock">
|
834
844
|
<div class="content">
|
835
845
|
<pre><tt>class Foobar
|
@@ -870,6 +880,8 @@ end</tt></pre>
|
|
870
880
|
Foobar, instead of the default, which is instances of Struct. This also
|
871
881
|
works the other way. You can now specify instances of Foobar as input to
|
872
882
|
the #insert, #update and #set methods. More on those methods below.</p>
|
883
|
+
<p>If the custom record class does not respond to #kb_create, KirbyBase will
|
884
|
+
call the class's #new method instead, passing it all of the field values.</p>
|
873
885
|
<div class="sidebarblock">
|
874
886
|
<div class="sidebar-content">
|
875
887
|
<div class="admonitionblock">
|
@@ -1372,6 +1384,35 @@ result.items.each { |item| puts '%d %d' % [item.item_no, item.qty] }</tt></pre>
|
|
1372
1384
|
<p>Notice how the items attribute in the ResultSet is itself a ResultSet
|
1373
1385
|
containing all of the :order_items records that belong to the selected
|
1374
1386
|
order.</p>
|
1387
|
+
<h3><a id="a-note-about-nil-values"></a>A Note About nil Values</h3>
|
1388
|
+
<p>Beginning in version 2.6 of KirbyBase, nil values are no longer stored as
|
1389
|
+
the singleton instance of NilClass in the database. Now, they are stored
|
1390
|
+
as references to the singleton instance, kb_nil, of KBNilClass. KBNilClass
|
1391
|
+
is as similar to NilClass as possible, but since NilClass cannot
|
1392
|
+
be sub-classed, there are a few minor differences.</p>
|
1393
|
+
<p>However, this should all be transparent to you because KirbyBase converts
|
1394
|
+
kb_nil values to Ruby nil values before returning the results of a query.
|
1395
|
+
The only time you will need to be worried about kb_nil is when you need to
|
1396
|
+
explicitly test for a nil value in a query. For example:</p>
|
1397
|
+
<div class="listingblock">
|
1398
|
+
<div class="content">
|
1399
|
+
<pre><tt>plane_tbl.select {|r| r.speed == kb_nil}</tt></pre>
|
1400
|
+
</div></div>
|
1401
|
+
<p>which is the same as:</p>
|
1402
|
+
<div class="listingblock">
|
1403
|
+
<div class="content">
|
1404
|
+
<pre><tt>plane_tbl.select {|r| r.speed.kb_nil?}</tt></pre>
|
1405
|
+
</div></div>
|
1406
|
+
<p>Notice how it is very similar to how you would test for nil?</p>
|
1407
|
+
<p>The only other difference you will now notice, is if you open up a table in
|
1408
|
+
a text editor. Now, nil values are stored as "kb_nil", instead of being
|
1409
|
+
stored as an empty string (i.e. ""). This has the added advantage that
|
1410
|
+
KirbyBase can now distinguish between empty strings and nil values. In the
|
1411
|
+
past, if you saved an empty string as a field value, the next time you
|
1412
|
+
selected that record, KirbyBase would return that field's value as nil.</p>
|
1413
|
+
<p>The main reason for making this change was to eliminate the need to
|
1414
|
+
override NilClass#method_missing, which was cause for concern for some
|
1415
|
+
users.</p>
|
1375
1416
|
</div>
|
1376
1417
|
<h2><a id="kbresultset"></a>KBResultSet</h2>
|
1377
1418
|
<div class="sectionbody">
|
@@ -1677,6 +1718,14 @@ lines:</p>
|
|
1677
1718
|
<div class="content">
|
1678
1719
|
<pre><tt>result = plane_tbl.pack</tt></pre>
|
1679
1720
|
</div></div>
|
1721
|
+
<div class="admonitionblock">
|
1722
|
+
<table><tr>
|
1723
|
+
<td class="icon">
|
1724
|
+
<img src="./images/important.png" alt="Important" />
|
1725
|
+
</td>
|
1726
|
+
<td class="content">You can only call this method when connect_type==:local.</td>
|
1727
|
+
</tr></table>
|
1728
|
+
</div>
|
1680
1729
|
<div class="sidebarblock">
|
1681
1730
|
<div class="sidebar-content">
|
1682
1731
|
<div class="admonitionblock">
|
@@ -1854,6 +1903,8 @@ than one recno.</p>
|
|
1854
1903
|
KirbyBase will attempt to convert the values in the csv file into their
|
1855
1904
|
corresponding KirbyBase field types, based upon the field types you
|
1856
1905
|
designated when you created the table.</p>
|
1906
|
+
<p>If you have FasterCSV installed KirbyBase will use it instead of CSV from
|
1907
|
+
the standard library.</p>
|
1857
1908
|
<p>Returns an Integer specifying the total number of records imported.</p>
|
1858
1909
|
</div></div>
|
1859
1910
|
<div class="sidebarblock">
|
@@ -2165,10 +2216,10 @@ text-file. Here is an example:</p>
|
|
2165
2216
|
first field in the header is the record counter. It is incremented by
|
2166
2217
|
KirbyBase to create new record numbers when records are inserted.</p>
|
2167
2218
|
<p>The second field in the header is the deleted-records counter. Every time a
|
2168
|
-
line in the file is blanked-out (see "The pack method
|
2169
|
-
incremented. You can use this field in a maintenance script so
|
2170
|
-
table is packed whenever the deleted-records counter reaches, say,
|
2171
|
-
records.</p>
|
2219
|
+
line in the file is blanked-out (see <a href="#pack-method">The pack method</a>), this
|
2220
|
+
number is incremented. You can use this field in a maintenance script so
|
2221
|
+
that the table is packed whenever the deleted-records counter reaches, say,
|
2222
|
+
5,000 records.</p>
|
2172
2223
|
<p>The third field in the header is the record_class field. If you specified a
|
2173
2224
|
class when you created the table, its name will show up here and records
|
2174
2225
|
returned from a #select will be instances of this class. The default is
|
@@ -2266,7 +2317,7 @@ an Array like all of the regular indexes. So selects are even faster.</p>
|
|
2266
2317
|
</div>
|
2267
2318
|
<div id="footer">
|
2268
2319
|
<div id="footer-text">
|
2269
|
-
Last updated
|
2320
|
+
Last updated 26-Jun-2006 14:36:38 EDT
|
2270
2321
|
</div>
|
2271
2322
|
</div>
|
2272
2323
|
</body>
|
data/lib/kirbybase.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'time'
|
3
3
|
require 'drb'
|
4
|
-
require 'csv'
|
5
4
|
require 'fileutils'
|
6
5
|
require 'yaml'
|
6
|
+
|
7
|
+
begin # first choice--for speed
|
8
|
+
require 'faster_csv'
|
9
|
+
rescue LoadError # second choice--slower but standard
|
10
|
+
require 'csv'
|
11
|
+
end
|
7
12
|
|
8
13
|
#
|
9
14
|
# :main:KirbyBase
|
@@ -152,11 +157,32 @@ require 'yaml'
|
|
152
157
|
# field, the default value will no longer override the user specified nil
|
153
158
|
# value. Thanks to Assaph Mehr for suggesting this.
|
154
159
|
#
|
160
|
+
# 2006-06-27:: Version 2.6
|
161
|
+
# * Removed NilClass#method_missing. I have replaced it with a new class
|
162
|
+
# called KBNilClass. Thanks to a host of people for help on this,
|
163
|
+
# including: Assaph Mehr, James Edward Gray II, Matthew Desmarais,
|
164
|
+
# Logan Capaldo, Trans, John Carter, Dave Burt and anyone else I missed.
|
165
|
+
# * Added conditional require logic so that KirbyBase will use FasterCVS if
|
166
|
+
# it is available. Thanks to James Edward Gray II for this.
|
167
|
+
# * You can now delay index creation in local mode. Thanks to Nicholas Rahn
|
168
|
+
# for this.
|
169
|
+
# * Added ability to allow for a custom record class with no kb_create or
|
170
|
+
# kb_defaults methods. KirbyBase will return each result record as an
|
171
|
+
# instance of the custom record class, and will attempt to set attributes
|
172
|
+
# with the same names as the table's field names equal to the values of
|
173
|
+
# the table record's fields. Thanks to Hal Fulton for this idea.
|
155
174
|
#
|
156
175
|
#---------------------------------------------------------------------------
|
157
176
|
# KBTypeConversionsMixin
|
158
177
|
#---------------------------------------------------------------------------
|
159
178
|
module KBTypeConversionsMixin
|
179
|
+
# Constant that will represent a kb_nil in the physical table file.
|
180
|
+
# If you think you might need to write the value 'kb_nil' to a field
|
181
|
+
# yourself, comment out the following line and un-comment the line
|
182
|
+
# below that to use an alternative representation for kb_nil.
|
183
|
+
KB_NIL = 'kb_nil'
|
184
|
+
#KB_NIL = '&kb_nil;'
|
185
|
+
|
160
186
|
# Regular expression used to determine if field needs to be un-encoded.
|
161
187
|
UNENCODE_RE = /&(?:amp|linefeed|carriage_return|substitute|pipe);/
|
162
188
|
|
@@ -170,7 +196,11 @@ module KBTypeConversionsMixin
|
|
170
196
|
# Return value converted from storage string to native field type.
|
171
197
|
#
|
172
198
|
def convert_to_native_type(data_type, s)
|
173
|
-
return
|
199
|
+
return kb_nil if s == KB_NIL
|
200
|
+
|
201
|
+
# I added this line to keep KBTable#import_csv working after I made
|
202
|
+
# the kb_nil changes.
|
203
|
+
return nil if s.nil?
|
174
204
|
|
175
205
|
case data_type
|
176
206
|
when :String
|
@@ -236,6 +266,8 @@ module KBTypeConversionsMixin
|
|
236
266
|
# Return value converted to encoded String object suitable for storage.
|
237
267
|
#
|
238
268
|
def convert_to_encoded_string(data_type, value)
|
269
|
+
return KB_NIL if value.nil?
|
270
|
+
|
239
271
|
case data_type
|
240
272
|
when :YAML
|
241
273
|
y = value.to_yaml
|
@@ -342,7 +374,7 @@ class KirbyBase
|
|
342
374
|
include DRb::DRbUndumped
|
343
375
|
include KBTypeConversionsMixin
|
344
376
|
|
345
|
-
VERSION = "2.
|
377
|
+
VERSION = "2.6"
|
346
378
|
|
347
379
|
attr_reader :engine
|
348
380
|
|
@@ -422,13 +454,9 @@ class KirbyBase
|
|
422
454
|
# happens when the table instance is first created, I go ahead and
|
423
455
|
# create table instances right off the bat.
|
424
456
|
#
|
425
|
-
#
|
426
|
-
#
|
427
|
-
|
428
|
-
# Everything should and does go through the table instances created
|
429
|
-
# on the client-side. You can turn this off by specifying true for
|
430
|
-
# the delay_index_creation argument.
|
431
|
-
if server? and @delay_index_creation
|
457
|
+
# You can delay index creation until the first time the index is
|
458
|
+
# used.
|
459
|
+
if @delay_index_creation
|
432
460
|
else
|
433
461
|
@engine.tables.each do |tbl|
|
434
462
|
@table_hash[tbl] = \
|
@@ -2121,11 +2149,7 @@ class KBTable
|
|
2121
2149
|
|
2122
2150
|
new_recno = @db.engine.insert_record(self, @field_names.zip(
|
2123
2151
|
@field_types).collect do |fn, ft|
|
2124
|
-
|
2125
|
-
''
|
2126
|
-
else
|
2127
|
-
convert_to_encoded_string(ft, input_rec[fn])
|
2128
|
-
end
|
2152
|
+
convert_to_encoded_string(ft, input_rec[fn])
|
2129
2153
|
end)
|
2130
2154
|
|
2131
2155
|
# If there are any associated memo/blob fields, save their values.
|
@@ -2751,7 +2775,9 @@ class KBTable
|
|
2751
2775
|
records_inserted = 0
|
2752
2776
|
tbl_rec = @table_class.new(self)
|
2753
2777
|
|
2754
|
-
|
2778
|
+
# read with FasterCSV if loaded, or the standard CSV otherwise
|
2779
|
+
(defined?(FasterCSV) ? FasterCSV : CSV).foreach(csv_filename
|
2780
|
+
) do |row|
|
2755
2781
|
tbl_rec.populate([nil] + row)
|
2756
2782
|
insert(tbl_rec)
|
2757
2783
|
records_inserted += 1
|
@@ -2923,12 +2949,12 @@ class KBTable
|
|
2923
2949
|
|
2924
2950
|
get_meth_upd_res_str = <<-END_OF_STRING
|
2925
2951
|
def #{field_name}_upd_res
|
2926
|
-
return
|
2952
|
+
return kb_nil
|
2927
2953
|
end
|
2928
2954
|
END_OF_STRING
|
2929
2955
|
set_meth_str = <<-END_OF_STRING
|
2930
2956
|
def #{field_name}=(s)
|
2931
|
-
@#{field_name} =
|
2957
|
+
@#{field_name} = kb_nil
|
2932
2958
|
end
|
2933
2959
|
END_OF_STRING
|
2934
2960
|
end
|
@@ -2944,12 +2970,12 @@ class KBTable
|
|
2944
2970
|
END_OF_STRING
|
2945
2971
|
get_meth_upd_res_str = <<-END_OF_STRING
|
2946
2972
|
def #{field_name}_upd_res()
|
2947
|
-
return
|
2973
|
+
return kb_nil
|
2948
2974
|
end
|
2949
2975
|
END_OF_STRING
|
2950
2976
|
set_meth_str = <<-END_OF_STRING
|
2951
2977
|
def #{field_name}=(s)
|
2952
|
-
@#{field_name} =
|
2978
|
+
@#{field_name} = kb_nil
|
2953
2979
|
end
|
2954
2980
|
END_OF_STRING
|
2955
2981
|
end
|
@@ -3081,9 +3107,17 @@ class KBTable
|
|
3081
3107
|
# Read header record and update instance variables.
|
3082
3108
|
#
|
3083
3109
|
def update_header_vars
|
3084
|
-
@encrypted, @last_rec_no, @del_ctr, @record_class, @
|
3085
|
-
@
|
3086
|
-
@
|
3110
|
+
@encrypted, @last_rec_no, @del_ctr, @record_class, @col_names, \
|
3111
|
+
@col_types, @col_indexes, @col_defaults, @col_requireds, \
|
3112
|
+
@col_extras = @db.engine.get_header_vars(self)
|
3113
|
+
|
3114
|
+
# These are deprecated.
|
3115
|
+
@field_names = @col_names
|
3116
|
+
@field_types = @col_types
|
3117
|
+
@field_indexes = @col_indexes
|
3118
|
+
@field_defaults = @col_defaults
|
3119
|
+
@field_requireds = @col_requireds
|
3120
|
+
@field_extras = @col_extras
|
3087
3121
|
end
|
3088
3122
|
|
3089
3123
|
#-----------------------------------------------------------------------
|
@@ -3118,30 +3152,51 @@ class KBTable
|
|
3118
3152
|
result_rec = result_struct.new(*filter.collect { |f|
|
3119
3153
|
tbl_rec.send("#{f}_upd_res".to_sym) })
|
3120
3154
|
elsif @record_class == 'Struct'
|
3121
|
-
result_rec = result_struct.new(*filter.collect
|
3122
|
-
|
3155
|
+
result_rec = result_struct.new(*filter.collect do |f|
|
3156
|
+
if tbl_rec.send(f).kb_nil?
|
3157
|
+
nil
|
3158
|
+
else
|
3159
|
+
tbl_rec.send(f)
|
3160
|
+
end
|
3161
|
+
end)
|
3123
3162
|
else
|
3124
3163
|
if Object.full_const_get(@record_class).respond_to?(:kb_create)
|
3125
3164
|
result_rec = Object.full_const_get(@record_class
|
3126
|
-
).kb_create(*@field_names.collect
|
3127
|
-
|
3128
|
-
|
3129
|
-
|
3130
|
-
|
3131
|
-
|
3132
|
-
|
3133
|
-
|
3134
|
-
|
3135
|
-
|
3136
|
-
|
3165
|
+
).kb_create(*@field_names.collect do |f|
|
3166
|
+
# Just a warning here: If you specify a filter on
|
3167
|
+
# a select, you are only going to get those fields
|
3168
|
+
# you specified in the result set, EVEN IF
|
3169
|
+
# record_class is a custom class instead of Struct.
|
3170
|
+
if filter.include?(f)
|
3171
|
+
if tbl_rec.send(f).kb_nil?
|
3172
|
+
nil
|
3173
|
+
else
|
3174
|
+
tbl_rec.send(f)
|
3175
|
+
end
|
3176
|
+
else
|
3177
|
+
nil
|
3178
|
+
end
|
3179
|
+
end)
|
3137
3180
|
elsif Object.full_const_get(@record_class).respond_to?(
|
3138
3181
|
:kb_defaults)
|
3139
3182
|
result_rec = Object.full_const_get(@record_class).new(
|
3140
|
-
*@field_names.collect
|
3141
|
-
|
3142
|
-
|
3143
|
-
|
3144
|
-
|
3183
|
+
*@field_names.collect do |f|
|
3184
|
+
if tbl_rec.send(f).kb_nil?
|
3185
|
+
nil
|
3186
|
+
else
|
3187
|
+
tbl_rec.send(f) || Object.full_const_get(
|
3188
|
+
@record_class).kb_defaults[@field_names.index(f)]
|
3189
|
+
end
|
3190
|
+
end)
|
3191
|
+
else
|
3192
|
+
result_rec = Object.full_const_get(@record_class).allocate
|
3193
|
+
@field_names.each do |fn|
|
3194
|
+
if tbl_rec.send(fn).kb_nil?
|
3195
|
+
result_rec.send("#{fn}=", nil)
|
3196
|
+
else
|
3197
|
+
result_rec.send("#{fn}=", tbl_rec.send(fn))
|
3198
|
+
end
|
3199
|
+
end
|
3145
3200
|
end
|
3146
3201
|
end
|
3147
3202
|
|
@@ -3413,30 +3468,12 @@ class KBIndex
|
|
3413
3468
|
# Split the line up into fields.
|
3414
3469
|
rec = line.split('|', @col_poss.max+2)
|
3415
3470
|
|
3416
|
-
|
3417
|
-
# that make up this index and converting them to their
|
3418
|
-
# native types.
|
3419
|
-
idx_rec = []
|
3420
|
-
@col_poss.zip(@col_types).each do |col_pos, col_type|
|
3421
|
-
idx_rec << convert_to_native_type(col_type,
|
3422
|
-
rec[col_pos])
|
3423
|
-
end
|
3424
|
-
|
3425
|
-
# Were all the index fields for this record equal to NULL?
|
3426
|
-
# Then don't add this index record to index array; skip to
|
3427
|
-
# next record.
|
3428
|
-
next if idx_rec.compact.empty?
|
3429
|
-
|
3430
|
-
# Add recno to the end of this index record.
|
3431
|
-
idx_rec << rec.first.to_i
|
3432
|
-
|
3433
|
-
# Add index record to index array.
|
3434
|
-
@idx_arr << idx_rec
|
3471
|
+
append_new_rec_to_index_array(rec)
|
3435
3472
|
end
|
3436
3473
|
# Here's how we break out of the loop...
|
3437
3474
|
rescue EOFError
|
3438
3475
|
end
|
3439
|
-
|
3476
|
+
|
3440
3477
|
@last_update = Time.new
|
3441
3478
|
end
|
3442
3479
|
|
@@ -3444,11 +3481,7 @@ class KBIndex
|
|
3444
3481
|
# add_index_rec
|
3445
3482
|
#-----------------------------------------------------------------------
|
3446
3483
|
def add_index_rec(rec)
|
3447
|
-
@
|
3448
|
-
convert_to_native_type(col_type, rec[col_pos])
|
3449
|
-
end + [rec.first.to_i]
|
3450
|
-
|
3451
|
-
@last_update = Time.new
|
3484
|
+
@last_upddate = Time.new if append_new_rec_to_index_array(rec)
|
3452
3485
|
end
|
3453
3486
|
|
3454
3487
|
#-----------------------------------------------------------------------
|
@@ -3467,6 +3500,22 @@ class KBIndex
|
|
3467
3500
|
delete_index_rec(rec.first.to_i)
|
3468
3501
|
add_index_rec(rec)
|
3469
3502
|
end
|
3503
|
+
|
3504
|
+
#-----------------------------------------------------------------------
|
3505
|
+
# append_new_rec_to_index_array
|
3506
|
+
#-----------------------------------------------------------------------
|
3507
|
+
def append_new_rec_to_index_array(rec)
|
3508
|
+
idx_rec = []
|
3509
|
+
@col_poss.zip(@col_types).each do |col_pos, col_type|
|
3510
|
+
idx_rec << convert_to_native_type(col_type, rec[col_pos])
|
3511
|
+
end
|
3512
|
+
|
3513
|
+
return false if idx_rec.uniq == [kb_nil]
|
3514
|
+
|
3515
|
+
idx_rec << rec.first.to_i
|
3516
|
+
@idx_arr << idx_rec
|
3517
|
+
return true
|
3518
|
+
end
|
3470
3519
|
end
|
3471
3520
|
|
3472
3521
|
|
@@ -3573,7 +3622,7 @@ class KBTableRec
|
|
3573
3622
|
|
3574
3623
|
def clear
|
3575
3624
|
@tbl.field_names.each do |fn|
|
3576
|
-
send("#{fn}=",
|
3625
|
+
send("#{fn}=", kb_nil)
|
3577
3626
|
end
|
3578
3627
|
end
|
3579
3628
|
end
|
@@ -3680,6 +3729,7 @@ class KBResultSet < Array
|
|
3680
3729
|
y << b_value
|
3681
3730
|
end
|
3682
3731
|
end
|
3732
|
+
|
3683
3733
|
x <=> y
|
3684
3734
|
}
|
3685
3735
|
end
|
@@ -3737,6 +3787,70 @@ class KBResultSet < Array
|
|
3737
3787
|
end
|
3738
3788
|
|
3739
3789
|
|
3790
|
+
#---------------------------------------------------------------------------
|
3791
|
+
# KBNilClass
|
3792
|
+
#---------------------------------------------------------------------------
|
3793
|
+
class KBNilClass
|
3794
|
+
include Comparable
|
3795
|
+
|
3796
|
+
class << self
|
3797
|
+
def new
|
3798
|
+
@kb_nil ||= KBNilClass.allocate
|
3799
|
+
end
|
3800
|
+
end
|
3801
|
+
|
3802
|
+
def inspect
|
3803
|
+
'kb_nil'
|
3804
|
+
end
|
3805
|
+
|
3806
|
+
def kb_nil?
|
3807
|
+
true
|
3808
|
+
end
|
3809
|
+
|
3810
|
+
def to_s
|
3811
|
+
""
|
3812
|
+
end
|
3813
|
+
|
3814
|
+
def to_i
|
3815
|
+
0
|
3816
|
+
end
|
3817
|
+
|
3818
|
+
def to_f
|
3819
|
+
0.0
|
3820
|
+
end
|
3821
|
+
|
3822
|
+
def to_a
|
3823
|
+
[]
|
3824
|
+
end
|
3825
|
+
|
3826
|
+
def <=>(other)
|
3827
|
+
return 0 if other.kb_nil?
|
3828
|
+
return -1
|
3829
|
+
end
|
3830
|
+
|
3831
|
+
def coerce(other)
|
3832
|
+
return [other, to_i] if other.kind_of? Fixnum
|
3833
|
+
return [other, to_f] if other.kind_of? Float
|
3834
|
+
|
3835
|
+
raise "Didn't know how to coerce kb_nil to a #{other.class}"
|
3836
|
+
end
|
3837
|
+
|
3838
|
+
def method_missing(sym, *args)
|
3839
|
+
kb_nil
|
3840
|
+
end
|
3841
|
+
end
|
3842
|
+
|
3843
|
+
|
3844
|
+
#---------------------------------------------------------------------------
|
3845
|
+
# Kernel
|
3846
|
+
#---------------------------------------------------------------------------
|
3847
|
+
module Kernel
|
3848
|
+
def kb_nil
|
3849
|
+
KBNilClass.new
|
3850
|
+
end
|
3851
|
+
end
|
3852
|
+
|
3853
|
+
|
3740
3854
|
#---------------------------------------------------------------------------
|
3741
3855
|
# Object
|
3742
3856
|
#---------------------------------------------------------------------------
|
@@ -3747,33 +3861,9 @@ class Object
|
|
3747
3861
|
list.each {|x| obj = obj.const_get(x) }
|
3748
3862
|
obj
|
3749
3863
|
end
|
3750
|
-
end
|
3751
3864
|
|
3752
|
-
|
3753
|
-
|
3754
|
-
# NilClass
|
3755
|
-
#---------------------------------------------------------------------------
|
3756
|
-
class NilClass
|
3757
|
-
#-----------------------------------------------------------------------
|
3758
|
-
# method_missing
|
3759
|
-
#-----------------------------------------------------------------------
|
3760
|
-
#
|
3761
|
-
# This code is necessary because if, inside a select condition code
|
3762
|
-
# block, there is a case where you are trying to do an expression
|
3763
|
-
# against a table field that is equal to nil, I don't want a method
|
3764
|
-
# missing exception to occur. I just want the expression to be nil. I
|
3765
|
-
# initially had this method returning false, but then I had an issue
|
3766
|
-
# where I had a YAML field that was supposed to hold an Array. If the
|
3767
|
-
# field was empty (i.e. nil) it was actually returning false when it
|
3768
|
-
# should be returning nil. Since nil evaluates to false, it works if I
|
3769
|
-
# return nil.
|
3770
|
-
# Here's an example:
|
3771
|
-
# #select { |r| r.speed > 300 }
|
3772
|
-
# What happens if speed is nil (basically NULL in DBMS terms)? Without
|
3773
|
-
# this code, an exception is going to be raised, which is not what we
|
3774
|
-
# really want. We really want this expression to return nil.
|
3775
|
-
def method_missing(method_id, *stuff)
|
3776
|
-
return nil
|
3865
|
+
def kb_nil?
|
3866
|
+
false
|
3777
3867
|
end
|
3778
3868
|
end
|
3779
3869
|
|
@@ -3802,3 +3892,5 @@ class Symbol
|
|
3802
3892
|
("+"+self.to_s).to_sym
|
3803
3893
|
end
|
3804
3894
|
end
|
3895
|
+
|
3896
|
+
|
data/test/tc_local_db.rb
CHANGED
data/test/tc_local_table.rb
CHANGED
@@ -766,5 +766,38 @@ class TestTableLocal < Test::Unit::TestCase
|
|
766
766
|
tbl.update(:one => ['two', 3]) { |r| r.recno == 1 }
|
767
767
|
assert_equal(['two', 3], tbl[1].one)
|
768
768
|
end
|
769
|
+
|
770
|
+
def test_nil_values_001
|
771
|
+
tbl = @db.create_table(:nil_tests, :nil_value, :Integer,
|
772
|
+
:conditional, :Integer)
|
773
|
+
tbl.insert(nil, 100)
|
774
|
+
|
775
|
+
recs = []
|
776
|
+
|
777
|
+
assert_nothing_raised {rec = tbl.select {|r| r.nil_value > 100}}
|
778
|
+
assert_equal 0, recs.length
|
779
|
+
|
780
|
+
assert_nothing_raised {recs = tbl.select {|r| r.nil_value > 100 and
|
781
|
+
r.conditional > 100}}
|
782
|
+
assert_equal 0, recs.length
|
783
|
+
|
784
|
+
assert_nothing_raised {recs = tbl.select {|r| r.nil_value > 100 or
|
785
|
+
r.conditional > 100}}
|
786
|
+
assert_equal 0, recs.length
|
787
|
+
|
788
|
+
assert_nothing_raised {recs = tbl.select {|r| r.nil_value > 100 and
|
789
|
+
r.conditional == 100}}
|
790
|
+
assert_equal 0, recs.length
|
791
|
+
|
792
|
+
assert_nothing_raised {recs = tbl.select {|r| r.nil_value > 100 or
|
793
|
+
r.conditional == 100}}
|
794
|
+
assert_equal 1, recs.length
|
795
|
+
|
796
|
+
assert_nothing_raised {recs = tbl.select {|r| r.nil_value.kb_nil?}}
|
797
|
+
assert_equal 1, recs.length
|
798
|
+
|
799
|
+
assert_nothing_raised {recs = tbl.select {|r| r.nil_value == kb_nil}}
|
800
|
+
assert_equal 1, recs.length
|
801
|
+
end
|
769
802
|
end
|
770
803
|
|
metadata
CHANGED
@@ -1,131 +1,134 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: KirbyBase
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 2.
|
7
|
-
date: 2006-
|
8
|
-
summary:
|
9
|
-
system."
|
6
|
+
version: "2.6"
|
7
|
+
date: 2006-06-27 00:00:00 -04:00
|
8
|
+
summary: KirbyBase is a simple, pure-Ruby, plain-text, flat-file database management system.
|
10
9
|
require_paths:
|
11
|
-
|
12
|
-
email: jcribbs@
|
10
|
+
- lib
|
11
|
+
email: jcribbs@netpromi.com
|
13
12
|
homepage: http://www.netpromi.com/kirbybase_ruby.html
|
14
13
|
rubyforge_project: kirbybase
|
15
|
-
description:
|
16
|
-
databases. You can use it in either a single-user or client-server mode. You can
|
17
|
-
select records for retrieval/updating using code blocks."
|
14
|
+
description: KirbyBase is a class that allows you to create and manipulate simple, plain-text databases. You can use it in either a single-user or client-server mode. You can select records for retrieval/updating using code blocks.
|
18
15
|
autorequire: kirbybase
|
19
16
|
default_executable:
|
20
17
|
bindir: bin
|
21
18
|
has_rdoc: true
|
22
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
23
20
|
requirements:
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
28
24
|
version:
|
29
25
|
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
30
28
|
authors:
|
31
|
-
|
29
|
+
- Jamey Cribbs
|
32
30
|
files:
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
31
|
+
- lib/kirbybase.rb
|
32
|
+
- bin/kbserver.rb
|
33
|
+
- README
|
34
|
+
- changes.txt
|
35
|
+
- kirbybaserubymanual.html
|
36
|
+
- test/base_test.rb
|
37
|
+
- test/tc_local_db.rb
|
38
|
+
- test/tc_local_table.rb
|
39
|
+
- test/ts_local.rb
|
40
|
+
- examples/aaa_try_this_first
|
41
|
+
- examples/add_column_test
|
42
|
+
- examples/calculated_field_test
|
43
|
+
- examples/change_column_type_test
|
44
|
+
- examples/column_required_test
|
45
|
+
- examples/crosstab_test
|
46
|
+
- examples/csv_import_test
|
47
|
+
- examples/default_value_test
|
48
|
+
- examples/drop_column_test
|
49
|
+
- examples/indexes_test
|
50
|
+
- examples/kbserver_as_win32_service
|
51
|
+
- examples/link_many_test
|
52
|
+
- examples/lookup_field_test
|
53
|
+
- examples/many_to_many_test
|
54
|
+
- examples/memo_test
|
55
|
+
- examples/record_class_test
|
56
|
+
- examples/rename_column_test
|
57
|
+
- examples/rename_table_test
|
58
|
+
- examples/yaml_field_test
|
59
|
+
- examples/aaa_try_this_first/kbtest.rb
|
60
|
+
- examples/add_column_test/add_column_test.rb
|
61
|
+
- examples/calculated_field_test/calculated_field_test.rb
|
62
|
+
- examples/change_column_type_test/change_column_type_test.rb
|
63
|
+
- examples/column_required_test/column_required_test.rb
|
64
|
+
- examples/crosstab_test/crosstab_test.rb
|
65
|
+
- examples/csv_import_test/csv_import_test.rb
|
66
|
+
- examples/csv_import_test/plane.csv
|
67
|
+
- examples/default_value_test/default_value_test.rb
|
68
|
+
- examples/drop_column_test/drop_column_test.rb
|
69
|
+
- examples/indexes_test/add_index_test.rb
|
70
|
+
- examples/indexes_test/drop_index_test.rb
|
71
|
+
- examples/indexes_test/index_test.rb
|
72
|
+
- examples/kbserver_as_win32_service/kbserverctl.rb
|
73
|
+
- examples/kbserver_as_win32_service/kbserver_daemon.rb
|
74
|
+
- examples/link_many_test/link_many_test.rb
|
75
|
+
- examples/lookup_field_test/lookup_field_test.rb
|
76
|
+
- examples/lookup_field_test/lookup_field_test_2.rb
|
77
|
+
- examples/lookup_field_test/the_hal_fulton_feature_test.rb
|
78
|
+
- examples/many_to_many_test/many_to_many_test.rb
|
79
|
+
- examples/memo_test/memos
|
80
|
+
- examples/memo_test/memo_test.rb
|
81
|
+
- examples/memo_test/memos/blank.txt
|
82
|
+
- examples/record_class_test/record_class_test.rb
|
83
|
+
- examples/record_class_test/record_class_test2.rb
|
84
|
+
- examples/rename_column_test/rename_column_test.rb
|
85
|
+
- examples/rename_table_test/rename_table_test.rb
|
86
|
+
- examples/yaml_field_test/yaml_field_test.rb
|
87
|
+
- images/blank.png
|
88
|
+
- images/callouts
|
89
|
+
- images/caution.png
|
90
|
+
- images/client_server.png
|
91
|
+
- images/example.png
|
92
|
+
- images/home.png
|
93
|
+
- images/important.png
|
94
|
+
- images/kirby1.jpg
|
95
|
+
- images/next.png
|
96
|
+
- images/note.png
|
97
|
+
- images/prev.png
|
98
|
+
- images/single_user.png
|
99
|
+
- images/smallnew.png
|
100
|
+
- images/tip.png
|
101
|
+
- images/toc-blank.png
|
102
|
+
- images/toc-minus.png
|
103
|
+
- images/toc-plus.png
|
104
|
+
- images/up.png
|
105
|
+
- images/warning.png
|
106
|
+
- images/callouts/1.png
|
107
|
+
- images/callouts/10.png
|
108
|
+
- images/callouts/11.png
|
109
|
+
- images/callouts/12.png
|
110
|
+
- images/callouts/13.png
|
111
|
+
- images/callouts/14.png
|
112
|
+
- images/callouts/15.png
|
113
|
+
- images/callouts/2.png
|
114
|
+
- images/callouts/3.png
|
115
|
+
- images/callouts/4.png
|
116
|
+
- images/callouts/5.png
|
117
|
+
- images/callouts/6.png
|
118
|
+
- images/callouts/7.png
|
119
|
+
- images/callouts/8.png
|
120
|
+
- images/callouts/9.png
|
122
121
|
test_files:
|
123
|
-
|
122
|
+
- test/ts_local.rb
|
124
123
|
rdoc_options: []
|
124
|
+
|
125
125
|
extra_rdoc_files: []
|
126
|
+
|
126
127
|
executables:
|
127
|
-
|
128
|
+
- kbserver.rb
|
128
129
|
extensions: []
|
130
|
+
|
129
131
|
requirements:
|
130
|
-
|
131
|
-
dependencies: []
|
132
|
+
- none
|
133
|
+
dependencies: []
|
134
|
+
|