KirbyBase 2.5

Sign up to get free protection for your applications and to get access to all the features.
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
+ }