Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] REBOL Relational Object-oriented Database

From: louisaturk::eudoramail::com at: 20-Jun-2001 4:09

Dear Carl and anyone else that might be able to help, I am hoping you can spare a few minutes to help me past a few problems. I am still working on a very simple character-based user interface for your database functions---see my unfinished work below. Once it is finished, I may try to put a View GUI on it, but for right now I want to keep it real simple so I can understand what is going on. I know I could use MySQL and avoid having to learn this, but I have reasons for wanting a full REBOL relational object-oriented dbms. I would really appreciate it if Carl Sassenrath would help with the core database functions as he is the most knowledgeable about the inner workings of REBOL, and it is he that provided the original functions that showed me the great potential of REBOL to do what I need done. I think that many others will also appreciate his concise, elegant contributions of basic building components to help us learn basic, practical skills. If Carl would please take out a few minutes to whip out the remaining needed function, I would be most thankful. Sorry to impose on him like this, but ask and ye shall receive. "Ye have not because ye ask not." You might want to do the program below, add a few records, and then step through the menu choices so that you can see what I am talking about in the following questions: 1. How can a field in a record be edited (not just replaced)? Carl, a function please. 2. What is the purpose of the 2 in the remove-data function? 3. Every time the insert-data function is called a box opens asking me for permission to write to disk. How do I prevent this in such a way as to not open my computer up for possible invasion? (Later: well, its not asking me now, but I don't know why.) 4. How do I print out a list of all or some of the fields in all of the records (say for a report)? I am using probe right now so I can at least see what is in the database, but I need formatted reports. 5. How can this database be related to a second database by say the phone number field? How can the data from both databases be accessed at once? 6. How can data be exported from a database as a comma separated file. 7. How can data be imported into a database from a comma separated file. 8. What is the maximum number of records practical to search with REBOL on a computer with 512 MB of RAM? With 20,000 records or so what would performance be like? 9. How can I get instant action upon pressing a key (say for a menu choice), without having to also hit the enter key? I hate to have to hit 2 keys when hitting one would work just as well. Thanks, Louis REBOL [Title: "REBOL Relational Object DBMS" Date: "19 June 2001" Version: 0.01 File: %db.r Author: "Carl Sessenrath and Louis A. Turk" Email: [louisaturk--eudoramail--com] Language: 'English Purpose: "A simple but complete relational object-oriented dbms." Comments: {Carl Sessenrath made these object oriented database management system functions as an example to teach me, Louis A. Turk, how to program an object database myself. Many thanks Carl! The comments about features below are mostly Carl's, edited by Louis for this script header. Features: 1. The db works from memory. Load-data brings it into memory where the find, remove and other functions operate on it. So, you have to load it first, or at least insert-data a few times to create some data records. 2. You can expand or reduce the record definition without corrupting or affecting the database. 3. If you expect to grow this database to a large size, you will want to MAKE HASH! the database when you load it. make the hash after the database is created (after the foreach loop). database: make hash! database But, don't worry about that until your database gets big. For a few hundred names, you don't need it. 4. The functions work like this: rec: find-data [bob--example--com] print rec/name print rec/phone etc. remove-data [bob--example--com] save-data ; write back to disk insert-data [kit--example--com] "Kitty Carson" none http:/www.a.com save-data ; write back to disk 5. You can use NONE for any missing value above. You don't need to do the save-data each time... but you must do it sooner or later. 6. The data is organized (keyed) by email. To change an email address, but keep the rest of the record intact, use the function change-data. Let's examine change-data: change-data: func [email-old email-new /local record] [ record: find database email-old if none? record [alert reform ["Missing record:" email-old] exit] insert clear first record email-new ; see note below ] Note: This is subtle, so should be noted... I'm clearing out the actual memory string for the old email, then inserting the new string into it. Also, this string is shared. It is used both in the database block (as the key) and in the record object itself. So changing it here will change it in both places. Please send any bug reports or features you add to: [louisaturk--eudoramail--com] } ; End of Comments ] ;End of Rebol Script Header ;#!/rebol/rebol -cs ;open/allow %data.r [read write] db-file: %data.r record: context [name: email: phone: web: none] ;Place the none value in all the varables. database: [] load-data: has [data] [ data: load/all db-file clear database foreach item data [ item: make record item repend database [item/email item] ] ] change-data: func [email-old email-new /local record] [ record: find database email-old if none? record [alert reform ["Missing record:" email-old] exit] insert clear first record email-new ; See note in feature #6 above. ] save-data: has [data] [ data: copy [] foreach [key obj] database [ append/only data third obj ] save db-file data ] find-data: func [email] [select database email] remove-data: func [email] [remove/part find database email 2] insert-data: func [email' name' phone' web'] [ repend database [ email' make record [ email: email' name: name' phone: phone' web: web' ] ] ] {Below is a simple character based user interface for REBOL/Core added by Louis A. Turk} load-data forever [ cls: "^(1B)[J" ; Clear the Screen. print cls print "^/ REBOL RELATIONAL OBJECT-ORIENTED DBMS" ; ^/ is a line feed. print " =====================================^/" print " 1. Add Record." print " 2. Edit a Field In a Record." print " 3. Delete Record." print " 4. Change Email Address Only." print " 5. Print Reports." print " 6. Exit.^/" choice: ask " Enter the number of your choice: " if choice = "1" [ forever [ print cls print " ADD A RECORD" print " ============^/" email: ask " Email Address : " if email = "" [break] rec: find database email if not rec = none [ print cls print " Record is already in database.^/" ask " Hit Any Key To Continue." break ] name: ask " Full Name : " phone: ask " Area Code & Phone# : " web: ask " Website URL : " insert-data email name phone web save-data ] ; End forever loop for choice 1 ] ; End if choice 1 if choice = "2" [ forever [ print cls print " EDIT A FIELD IN A RECORD" print " ========================^/" email-old: ask " Email Address: " record: find database email-old if record = none [ print cls print "^/ Missing record: " email-old ask "^/ Hit Any Key To Continue." break ] record: find-data email-old print ["^/ 1. Email : " record/email] print [" 2. Name : " record/name] print [" 3. Phone : " record/phone] print [" 4. URL : " record/web "^/"] choice: ask " Enter number of field to change: " ; I'm using this method of accessing fields since records in databases ; to be expanded from this one may have 10 to 30 fields with only ; one usually needing editing. if choice = "1" [ print cls print " EDIT EMAIL ADDRESS" print " ==================^/" ask "New function needed here to edit the email field." save-data choice: "0" ;print ["The email address has been changed to " email-new "."] ] if choice = "2" [ print cls print " CHANGE NAME" print " ===========^/" name-old: record/name ask "New function needed here to edit the name field." save-data choice: "0" ] if choice = "3" [ print cls print " CHANGE PHONE" print " ===========^/" ask "New function needed here to edit the phone number field." save-data choice: "0" ] if choice = "4" [ print cls print " CHANGE URL" print " ===========^/" ask "New function needed here to edit the url field." save-data choice: "0" ] ] ; End forever loop ] ; End if choice 2 if choice = "3" [ forever [ print cls print " DELETE A RECORD" print " ===============^/" email-old: ask " Email Address Of Record To Delete: " if email-old = "" [ break ] ; End if. record: find database email-old if none? record [ print cls print " Record not found.^/" ask " Hit Any Key To Continue." break ] remove-data email-old save-data ] ; End forever loop for choice 3. ] ; End if choice 3 if choice = "4" [ forever [ print cls print " CHANGE EMAIL ADDRESS ONLY" print " ==========================^/" email-old: ask " Email Address To Be Changed: " record: find database email-old if none? record [ print cls print "Missing record: " email-old ask "Hit Any Key To Continue." break ] email-new: ask " New Email Address: " change-data email-old email-new save-data ] ; End forever loop for choice 4 ] ; End if choice 4 if choice = "5" [ print cls print " PRINT FORMATTED REPORTS" print " =======================^/" print "I need to know how to print formatted reports, instead of just using probe as below.^/" probe database ask "Press Enter To Continue." ] if choice = "6" [ break ] ; End if choice 6 if choice > "6" [ print "Error: Choice must be number between 1 and 6.^/" ask "Hit Any Key To Continue." ] ; End if for choice 6. ] ; End forever loop for main program.