KirbyBase 2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/README +73 -0
  2. data/bin/kbserver.rb +20 -0
  3. data/changes.txt +105 -0
  4. data/examples/aaa_try_this_first/kbtest.rb +207 -0
  5. data/examples/add_column_test/add_column_test.rb +27 -0
  6. data/examples/calculated_field_test/calculated_field_test.rb +51 -0
  7. data/examples/change_column_type_test/change_column_type_test.rb +25 -0
  8. data/examples/column_required_test/column_required_test.rb +33 -0
  9. data/examples/crosstab_test/crosstab_test.rb +100 -0
  10. data/examples/csv_import_test/csv_import_test.rb +31 -0
  11. data/examples/csv_import_test/plane.csv +11 -0
  12. data/examples/default_value_test/default_value_test.rb +43 -0
  13. data/examples/drop_column_test/drop_column_test.rb +24 -0
  14. data/examples/indexes_test/add_index_test.rb +46 -0
  15. data/examples/indexes_test/drop_index_test.rb +66 -0
  16. data/examples/indexes_test/index_test.rb +71 -0
  17. data/examples/kbserver_as_win32_service/kbserver_daemon.rb +47 -0
  18. data/examples/kbserver_as_win32_service/kbserverctl.rb +75 -0
  19. data/examples/link_many_test/link_many_test.rb +70 -0
  20. data/examples/lookup_field_test/lookup_field_test.rb +55 -0
  21. data/examples/lookup_field_test/lookup_field_test_2.rb +62 -0
  22. data/examples/lookup_field_test/the_hal_fulton_feature_test.rb +69 -0
  23. data/examples/many_to_many_test/many_to_many_test.rb +65 -0
  24. data/examples/memo_test/memo_test.rb +63 -0
  25. data/examples/memo_test/memos/blank.txt +0 -0
  26. data/examples/record_class_test/record_class_test.rb +77 -0
  27. data/examples/rename_column_test/rename_column_test.rb +46 -0
  28. data/examples/rename_table_test/rename_table_test.rb +38 -0
  29. data/examples/yaml_field_test/yaml_field_test.rb +47 -0
  30. data/images/blank.png +0 -0
  31. data/images/callouts/1.png +0 -0
  32. data/images/callouts/10.png +0 -0
  33. data/images/callouts/11.png +0 -0
  34. data/images/callouts/12.png +0 -0
  35. data/images/callouts/13.png +0 -0
  36. data/images/callouts/14.png +0 -0
  37. data/images/callouts/15.png +0 -0
  38. data/images/callouts/2.png +0 -0
  39. data/images/callouts/3.png +0 -0
  40. data/images/callouts/4.png +0 -0
  41. data/images/callouts/5.png +0 -0
  42. data/images/callouts/6.png +0 -0
  43. data/images/callouts/7.png +0 -0
  44. data/images/callouts/8.png +0 -0
  45. data/images/callouts/9.png +0 -0
  46. data/images/caution.png +0 -0
  47. data/images/client_server.png +0 -0
  48. data/images/example.png +0 -0
  49. data/images/home.png +0 -0
  50. data/images/important.png +0 -0
  51. data/images/kirby1.jpg +0 -0
  52. data/images/next.png +0 -0
  53. data/images/note.png +0 -0
  54. data/images/prev.png +0 -0
  55. data/images/single_user.png +0 -0
  56. data/images/smallnew.png +0 -0
  57. data/images/tip.png +0 -0
  58. data/images/toc-blank.png +0 -0
  59. data/images/toc-minus.png +0 -0
  60. data/images/toc-plus.png +0 -0
  61. data/images/up.png +0 -0
  62. data/images/warning.png +0 -0
  63. data/kirbybaserubymanual.html +2243 -0
  64. data/lib/kirbybase.rb +3662 -0
  65. metadata +126 -0
@@ -0,0 +1,47 @@
1
+ # Modified version of kbserver.rb for use as Windows Service.
2
+
3
+ require 'kirbybase'
4
+ require 'drb'
5
+ require 'win32/service'
6
+ include Win32
7
+
8
+ OPTIONS = {}
9
+
10
+ class KBServerDaemon < Daemon
11
+ def initialize
12
+ # NOTE: Change this line to reflect where you want the log file to
13
+ # reside.
14
+ @log = 'C:\logs\db_server_log.txt'
15
+ begin
16
+ # NOTE: Change this line to reflect where the database tables
17
+ # are located.
18
+ @db = KirbyBase.new do |x|
19
+ x.connect_type = :server
20
+ x.path = 'C:\data'
21
+ end
22
+ rescue Exception => e
23
+ File.open(@log, "a+") { |fh| ft.puts "Error: #{e}" }
24
+ service_stop
25
+ end
26
+ end
27
+
28
+ def service_main
29
+ begin
30
+ # NOTE: Change this line to reflect what port you want to
31
+ # listen on.
32
+ DRb.start_service('druby://:44444', @db)
33
+ DRb.thread.join
34
+ rescue StandardError, InterrupError => e
35
+ File.open(@log, "a+") { |fh| fh.puts "Error: #{e}" }
36
+ service_stop
37
+ end
38
+ end
39
+
40
+ def service_stop
41
+ DRb.stop_service
42
+ exit
43
+ end
44
+ end
45
+
46
+ d = KBServerDaemon.new
47
+ d.mainloop
@@ -0,0 +1,75 @@
1
+ # Control script for the KBServer service.
2
+
3
+ require 'optparse'
4
+ require 'win32/service'
5
+ include Win32
6
+
7
+ # You will want to change these values.
8
+ kbserver_home = 'C:\kbserver'
9
+ kbserver_prog = kbserver_home + '\kbserver_daemon.rb'
10
+ kbserver_svc = 'KirbyBaseServerSvc'
11
+ kbserver_name = 'KirbyBase Database Server'
12
+
13
+ OPTIONS = {}
14
+
15
+ ARGV.options do |opts|
16
+ opts.on("-d", "--delete", "Delete the service") {
17
+ OPTIONS[:delete] = true }
18
+ opts.on("-s", "--start", "Start the service") {
19
+ OPTIONS[:start] = true }
20
+ opts.on("-x", "--stop", "Stop the service") {
21
+ OPTIONS[:stop] = true }
22
+ opts.on("-i", "--install", "Install the service") {
23
+ OPTIONS[:install] = true }
24
+ opts.on("-h", "--help", "Show this help message") {
25
+ puts opts; exit }
26
+ opts.parse!
27
+ end
28
+
29
+ # Install the service.
30
+ if OPTIONS[:install]
31
+ svc = Service.new
32
+ svc.create_service do |s|
33
+ s.service_name = kbserver_svc
34
+ s.display_name = kbserver_name
35
+ s.binary_path_name = 'c:\ruby\bin\ruby.exe ' + kbserver_prog
36
+ # This is required for now - bug in win32-service
37
+ s.dependencies = []
38
+ end
39
+ svc.close
40
+ puts "KirbyBase Server service installed"
41
+ end
42
+
43
+ # Start the service.
44
+ if OPTIONS[:start]
45
+ Service.start(kbserver_svc)
46
+ started = false
47
+ while started == false
48
+ s = Service.status(kbserver_svc)
49
+ started = true if s.current_state == "running"
50
+ break if started == true
51
+ puts "One moment, " + s.current_state
52
+ sleep 1
53
+ end
54
+ puts "KirbyBase Server service started"
55
+ end
56
+
57
+ # Stop the service.
58
+ if OPTIONS[:stop]
59
+ begin
60
+ Service.stop(kbserver_svc)
61
+ rescue
62
+ end
63
+ puts "KirbyBase Server service stopped"
64
+ end
65
+
66
+ # Delete the service. Stop it first.
67
+ if OPTIONS[:delete]
68
+ begin
69
+ Service.stop(kbserver_svc)
70
+ rescue
71
+ end
72
+ Service.delete(kbserver_svc)
73
+ puts "KirbyBase Server service deleted"
74
+ end
75
+
@@ -0,0 +1,70 @@
1
+ # This script demonstrates how to link a field in the table to a subset
2
+ # of records from another table (i.e. a "one to many" link in database
3
+ # lingo).
4
+
5
+ # In this example, we have an order table and an order_item table. Each
6
+ # record in the order table represents a customer order. The order_item
7
+ # table holds the detail items for each order. We create a one-to-many link
8
+ # between the order table and the order_item table by providing extra
9
+ # information about the order.items field when we create the order table.
10
+
11
+ require 'kirbybase'
12
+
13
+ db = KirbyBase.new
14
+
15
+ # To run as a client in a multi-user environment, uncomment next line.
16
+ # Also, make sure kbserver.rb is running.
17
+ #db = KirbyBase.new do |d|
18
+ # d.connect_type = :client
19
+ # d.host = 'localhost'
20
+ # d.port = 44444
21
+ #end
22
+
23
+ # If table exists, delete it.
24
+ db.drop_table(:order) if db.table_exists?(:order)
25
+ db.drop_table(:order_item) if db.table_exists?(:order_item)
26
+
27
+ # Create an order item table. This is the child table to the order table.
28
+ # Create child table before creating parent table so that KirbyBase can
29
+ # take advantage of any indexes.
30
+ order_item_tbl = db.create_table(:order_item,
31
+ :item_id, :Integer,
32
+ :order_id, :Integer,
33
+ :descr, :String,
34
+ :qty, :Integer,
35
+ :price, :Float
36
+ )
37
+
38
+ # Create a table. We are telling KirbyBase that the items field is
39
+ # to be linked to the order_item table by comparing the order.order_id
40
+ # field to the order_item.order_id field. By specifying :Link_many, we are
41
+ # telling KirbyBase to make this a one-to-many link. The result of this is
42
+ # that when you do a select, the items field of the order table is going to
43
+ # hold a reference to a ResultSet (i.e. Array) holding all order_item
44
+ # records whose order_id field match the order_id field in the order record.
45
+ order_tbl = db.create_table(:order,
46
+ :order_id, :Integer,
47
+ :customer, :String,
48
+ :items, {:DataType=> :ResultSet, :Link_many=> [:order_id, :order_item,
49
+ :order_id]}
50
+ )
51
+
52
+ # Insert some order records.
53
+ order_tbl.insert({:order_id=>345, :customer=>'Ford'})
54
+ order_tbl.insert({:order_id=>454, :customer=>'Microsoft'})
55
+ order_tbl.insert({:order_id=>17, :customer=>'Boeing'})
56
+
57
+ # Insert some order item records.
58
+ order_item_tbl.insert(1,345,'Steel',30,19.99)
59
+ order_item_tbl.insert(2,345,'Glass',5,4.15)
60
+ order_item_tbl.insert(5,454,'Floppies',750000,0.5)
61
+ order_item_tbl.insert(3,17,'Wheels',200,2500.0)
62
+ order_item_tbl.insert(4,17,'Wings',25,1000000.0)
63
+
64
+ # Print all orders. Under each order print all items in that order.
65
+ order_tbl.select.each do |r|
66
+ puts '%3d %s' % [r.order_id, r.customer]
67
+ r.items.each { |i|
68
+ puts "\t%d %15s %6d %10.2f" % [i.item_id, i.descr, i.qty, i.price]
69
+ }
70
+ end
@@ -0,0 +1,55 @@
1
+ # This script demonstrates how to link a field in the table to an entire
2
+ # record from another table (i.e. a "one to one" relationship in database
3
+ # lingo).
4
+
5
+ # In the example below, we have a department table. For each department
6
+ # record, the manager field is actually a reference to a record from the
7
+ # person table. This allows us to reference the linked person record
8
+ # through the manager field.
9
+
10
+ require 'kirbybase'
11
+
12
+ db = KirbyBase.new
13
+
14
+ # To run as a client in a multi-user environment, uncomment next line.
15
+ # Also, make sure kbserver.rb is running.
16
+ #db = KirbyBase.new do |d|
17
+ # d.connect_type = :client
18
+ # d.host = 'localhost'
19
+ # d.port = 44444
20
+ #end
21
+
22
+ # If tables exists, delete them.
23
+ db.drop_table(:department) if db.table_exists?(:department)
24
+ db.drop_table(:person) if db.table_exists?(:person)
25
+
26
+ # Create a person table. Create lookup table first before the table that
27
+ # uses the lookup table, so that KirbyBase can take advantage of any
28
+ # indexes.
29
+ person_tbl = db.create_table(:person,
30
+ :person_id, :String,
31
+ :name, :String,
32
+ :phone, :String
33
+ )
34
+
35
+ # Insert some person records.
36
+ person_tbl.insert('000-13-5031', 'John Smith', '512.555.1234')
37
+ person_tbl.insert('010-10-9999', 'Jane Doe', '313.724.4230')
38
+
39
+ # Create a table. We are telling KirbyBase that the manager field is
40
+ # to be linked to the person table.
41
+ department_tbl = db.create_table(:department,
42
+ :dept_id, :Integer,
43
+ :dept_name, :String,
44
+ :manager, {:DataType=>:String, :Lookup=>[:person, :person_id]})
45
+
46
+ # Insert some department records.
47
+ department_tbl.insert(345, 'Payroll', '000-13-5031')
48
+ department_tbl.insert(442, 'Accounting', '010-10-9999')
49
+
50
+ # Print department info. Notice how we also print info from the linked
51
+ # person record.
52
+ department_tbl.select.each do |r|
53
+ puts "\n%s %s %s %s %s" % [r.dept_id, r.dept_name,
54
+ r.manager.person_id, r.manager.name, r.manager.phone]
55
+ end
@@ -0,0 +1,62 @@
1
+ # This script demonstrates how to link a field in the table to an entire
2
+ # record from another table (sometimes called a "lookup table"). This
3
+ # script is different from 'lookup_field_test.rb' because it shows how to
4
+ # use the "lookup_key" table attribute to make it easier to define a
5
+ # Lookup field.
6
+
7
+ # In the example below, we have a department table. For each department
8
+ # record, the manager field is actually a reference to a record from the
9
+ # person table. This allows us to reference the linked person record
10
+ # through the manager field.
11
+
12
+ require 'kirbybase'
13
+
14
+ db = KirbyBase.new
15
+
16
+ # To run as a client in a multi-user environment, uncomment next line.
17
+ # Also, make sure kbserver.rb is running.
18
+ #db = KirbyBase.new do |d|
19
+ # d.connect_type = :client
20
+ # d.host = 'localhost'
21
+ # d.port = 44444
22
+ #end
23
+
24
+ # If tables exists, delete them.
25
+ db.drop_table(:department) if db.table_exists?(:department)
26
+ db.drop_table(:person) if db.table_exists?(:person)
27
+
28
+ # Create a person table. Create lookup table first before the table that
29
+ # uses the lookup table, so that KirbyBase can take advantage of any
30
+ # indexes. Also, we want to create the lookup table first so that we can
31
+ # define a lookup key. We do this by adding a :Key entry to the field type
32
+ # has and assigning true to it's value.
33
+ person_tbl = db.create_table(:person,
34
+ :person_id, {:DataType=>:String, :Key=>true},
35
+ :name, :String,
36
+ :phone, :String
37
+ )
38
+
39
+ # Insert some person records.
40
+ person_tbl.insert('000-13-5031', 'John Smith', '512.555.1234')
41
+ person_tbl.insert('010-10-9999', 'Jane Doe', '313.724.4230')
42
+
43
+ # Create a table. We are telling KirbyBase that the manager field is
44
+ # to be linked to the person table. Notice that in this example, since we
45
+ # want the manager field in this table to be linked to the person_id in the
46
+ # person table, which is that table's lookup key field, all we have to
47
+ # specify here is the name of the lookup table, :person.
48
+ department_tbl = db.create_table(:department,
49
+ :dept_id, :Integer,
50
+ :dept_name, :String,
51
+ :manager, {:DataType=>:String, :Lookup=>:person})
52
+
53
+ # Insert some department records.
54
+ department_tbl.insert(345, 'Payroll', '000-13-5031')
55
+ department_tbl.insert(442, 'Accounting', '010-10-9999')
56
+
57
+ # Print department info. Notice how we also print info from the linked
58
+ # person record.
59
+ department_tbl.select.each do |r|
60
+ puts "\n%s %s %s %s %s" % [r.dept_id, r.dept_name,
61
+ r.manager.person_id, r.manager.name, r.manager.phone]
62
+ end
@@ -0,0 +1,69 @@
1
+ # This script demonstrates how to link a field in the table to an entire
2
+ # record from another table (sometimes called a "lookup table"). This
3
+ # script is different from 'lookup_field_test_2.rb' because it shows how to
4
+ # define a Lookup field in an even easier way, by just specifying the
5
+ # lookup table as the field type for the lookup field. KirbyBase will
6
+ # determine the field type for the lookup field by looking at the field
7
+ # type of the key field of the lookup table. This is a feature that Hal
8
+ # Fulton has been asking for so I named it in honor of him. :)
9
+
10
+ # In the example below, we have a department table. For each department
11
+ # record, the manager field is actually a reference to a record from the
12
+ # person table. This allows us to reference the linked person record
13
+ # through the manager field.
14
+
15
+ require 'kirbybase'
16
+
17
+ db = KirbyBase.new
18
+
19
+ # To run as a client in a multi-user environment, uncomment next line.
20
+ # Also, make sure kbserver.rb is running.
21
+ #db = KirbyBase.new do |d|
22
+ # d.connect_type = :client
23
+ # d.host = 'localhost'
24
+ # d.port = 44444
25
+ #end
26
+
27
+ # If tables exists, delete them.
28
+ db.drop_table(:department) if db.table_exists?(:department)
29
+ db.drop_table(:person) if db.table_exists?(:person)
30
+
31
+ # Create a person table. Create lookup table first before the table that
32
+ # uses the lookup table, so that KirbyBase can take advantage of any
33
+ # indexes. Also, we want to create the lookup table first so that we can
34
+ # define a lookup key. We do this by adding a :Key entry to the field type
35
+ # has and assigning true to it's value.
36
+ person_tbl = db.create_table(:person,
37
+ :person_id, {:DataType=>:String, :Key=>true},
38
+ :name, :String,
39
+ :phone, :String
40
+ )
41
+
42
+ # Insert some person records.
43
+ person_tbl.insert('000-13-5031', 'John Smith', '512.555.1234')
44
+ person_tbl.insert('010-10-9999', 'Jane Doe', '313.724.4230')
45
+
46
+ # Create a table. We are telling KirbyBase that the manager field is
47
+ # to be linked to the person table. Notice that in this example, since we
48
+ # want the manager field in this table to be linked to the person_id in the
49
+ # person table, which is that table's lookup key field, all we have to
50
+ # specify here is the name of the lookup table, :person. We don't even
51
+ # have to specify the field type for the :manager field, because
52
+ # KirbyBase will look at the field type definition for :person.person_id
53
+ # to automatically assign :manager the same field type (i.e. :String).
54
+
55
+ department_tbl = db.create_table(:department,
56
+ :dept_id, :Integer,
57
+ :dept_name, :String,
58
+ :manager, :person)
59
+
60
+ # Insert some department records.
61
+ department_tbl.insert(345, 'Payroll', '000-13-5031')
62
+ department_tbl.insert(442, 'Accounting', '010-10-9999')
63
+
64
+ # Print department info. Notice how we also print info from the linked
65
+ # person record.
66
+ department_tbl.select.each do |r|
67
+ puts "\n%s %s %s %s %s" % [r.dept_id, r.dept_name,
68
+ r.manager.person_id, r.manager.name, r.manager.phone]
69
+ end
@@ -0,0 +1,65 @@
1
+ # This script demonstrates how you could do many-to-many relationships in
2
+ # KirbyBase.
3
+
4
+ require 'kirbybase'
5
+
6
+ db = KirbyBase.new
7
+
8
+ # Delete tables if they already exist.
9
+ db.drop_table(:author) if db.table_exists?(:author)
10
+ db.drop_table(:book) if db.table_exists?(:book)
11
+ db.drop_table(:book_author) if db.table_exists?(:book_author)
12
+
13
+ # Create author table. Notice how we are creating a one-to-many link to
14
+ # the book_author table.
15
+ author_tbl = db.create_table(:author,
16
+ :author_id, :Integer, :name, :String,
17
+ :books, {:DataType=>:ResultSet,
18
+ :Link_many=>[:author_id, :book_author, :author_id]}
19
+ )
20
+
21
+ # Create book table. Notice how we are creating a one-to-many link to
22
+ # the book_author table.
23
+ book_tbl = db.create_table(:book,
24
+ :book_id, :Integer, :title, :String,
25
+ :authors, {:DataType=>:ResultSet,
26
+ :Link_many=>[:book_id, :book_author, :book_id]}
27
+ )
28
+
29
+ # Create join table that will connect author table and book table.
30
+ book_author_tbl = db.create_table(:book_author, :book_id, :Integer,
31
+ :author_id, :Integer)
32
+
33
+ # Insert some author records.
34
+ author_tbl.insert(1, 'Jules Verne', nil)
35
+ author_tbl.insert(2, 'Margaret Weis', nil)
36
+ author_tbl.insert(3, 'Tracy Hickman', nil)
37
+
38
+ # Insert some book records.
39
+ book_tbl.insert(1, 'Voyage to the Bottom of the Sea', nil)
40
+ book_tbl.insert(2, 'From the Earth to the Moon', nil)
41
+ book_tbl.insert(3, 'Dragons of Winter Night', nil)
42
+ book_tbl.insert(4, 'The Nightmare Lands', nil)
43
+
44
+ # Insert some records into the book_author table that will link the book
45
+ # table to the author table.
46
+ book_author_tbl.insert(1, 1)
47
+ book_author_tbl.insert(2, 1)
48
+ book_author_tbl.insert(3, 2)
49
+ book_author_tbl.insert(3, 3)
50
+ book_author_tbl.insert(4, 2)
51
+ book_author_tbl.insert(4, 3)
52
+
53
+
54
+ # Show all book titles written by Jules Verne.
55
+ author_tbl.select { |r| r.name == 'Jules Verne'
56
+ }.first.books.each { |b|
57
+ puts book_tbl.select { |r| r.book_id == b.book_id }.first.title
58
+ }
59
+ puts
60
+
61
+ # Show the authors of "The Nightmare Lands".
62
+ book_tbl.select { |r| r.title == 'The Nightmare Lands'
63
+ }.first.authors.each { |a|
64
+ puts author_tbl.select { |r| r.author_id == a.author_id }.first.name
65
+ }