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

[DEV] dbms3.r 02

 [1/4] from: g::santilli::tiscalinet::it at: 19-Jan-2002 15:58


PROJECT NAME: dbms3.r (temporary) PURPOSE: writing a small and simple relational database management system in REBOL, for use with applications that don't need a full blown separate DBMS such as MySQL. With respect to dbms.r, it will be more efficient in the data storage to be usable with much more rows per table, and possibly will have a more powerful/abstracted interface. DEVELOPMENT, part 2 here i am again... didn't expect to cause all that traffic. i'll go off-list soon. first, let me make a correction to the low level interface: -- memory-table-funcs: context [ ; memory-table-funcs-code row-append: func [ "Append a row to an on-memory table" table [object!] row [block!] ; returns the row-id of the new row ] row-append-code row-pick: func [ "Pick a row from an on-memory table" table [object!] row-id [integer!] ; returns the row or none! for an invalid row-id ] row-pick-code row-change: func [ "Change a row in an on-memory table" table [object!] row-id [integer!] new-row [block!] ; returns the row-id of the changed row, or none! for ; an invalid row-id ] row-change-code row-remove: func [ "Remove a row from an on-memory table" table [object!] row-id [integer!] ; returns true, or false if the row-id is invalid ] row-remove-code ] -- you see i changed object! to block! for rows; object!s should be handled at a higher level than this. i also changed the argument name for row-change so that it is clearer that it needs a complete new row now. now we can start with the code; we'll need to know how an in memory table object! looks like. at this time we just need: -- create-memory-table: func [ "Create a new on-memory table" ; returns the new table object! ] [ context [ data: make block! 1024 ] ] -- so... -- row-append: func [ "Append a row to an on-memory table" table [object!] row [block!] ; returns the row-id of the new row ] [ ; row-append-code insert/only tail table/data row length? table/data ] -- wrt the discussions on the list, the row-id is the position in the block, so it is implicitly present; the status we are interested with in this case can only be "present" or "deleted": so it is present when the element in the data block is a block and is deleted when it is none. this way row-pick will magically work as: -- row-pick: func [ "Pick a row from an on-memory table" table [object!] row-id [integer!] ; returns the row or none! for an invalid row-id ] [ ; row-pick-code pick table/data row-id ] -- for in-memory tables the row-id does not need to change upon record changes, and row-change will be as simple as: -- row-change: func [ "Change a row in an on-memory table" table [object!] row-id [integer!] new-row [block!] ; returns the row-id of the changed row, or none! for ; an invalid row-id ] [ ; row-change-code poke table/data row-id new-row row-id ] -- well, actually it needs some error checking. row-id should not be greater than length? table/data and should not refer to a deleted record. if this happens, none! should be returned. pick handles both the cases well. -- row-change: func [ "Change a row in an on-memory table" table [object!] row-id [integer!] new-row [block!] ; returns the row-id of the changed row, or none! for ; an invalid row-id ] [ ; row-change-code if not found? pick table/data row-id [ return none ] poke table/data row-id new-row row-id ] -- as last: -- row-remove: func [ "Remove a row from an on-memory table" table [object!] row-id [integer!] ; returns true, or false if the row-id is invalid ] [ either found? pick table/data row-id [ poke table/data row-id none true ] [ false ] ] -- time for a bit of testing, heh? i'm using test code such as: -- test-code: func [code] [ print [ "Call: " trim/lines mold code newline "Result:" newline mold do code ] ] random/seed now print "On Memory low-level functions test" print "*********************************************" print "Creating table" test-code [ test-table: create-memory-table ] print "*********************************************" print "Simple test" test-code [row-append test-table [1 2 3]] test-code [row-pick test-table 1] test-code [row-change test-table 1 [4 5 6]] test-code [row-pick test-table 1] test-code [row-remove test-table 1] test-code [row-pick test-table 1] test-code [row-change test-table 1 [7 8 9]] test-code [row-pick test-table 1] print "*********************************************" print "RANDOM test" print "*********************************************" print ["Testing row-append for" n: random 1024 "runs"] loop n [ test-code compose/deep [ row-append test-table [ (random 10) (random 10) (random 10) ] ] ] print "*********************************************" print ["Testing row-pick for" n: random 100 "runs"] loop n [ test-code compose [row-pick test-table (random 1024)] ] print "*********************************************" print ["Testing row-change for" n: random 100 "runs"] loop n [ test-code compose/deep [ row-change test-table (random 1024) [ (random 10) (random 10) (random 10) ] ] ] print "*********************************************" print ["Testing row-pick for" n: random 100 "runs"] loop n [ test-code compose [row-pick test-table (random 1024)] ] print "*********************************************" print ["Testing row-remove for" n: random 100 "runs"] loop n [ test-code compose [row-remove test-table (random 1024)] ] print "*********************************************" print ["Testing row-change for" n: random 100 "runs"] loop n [ test-code compose/deep [ row-change test-table (random 1024) [ (random 10) (random 10) (random 10) ] ] ] print "*********************************************" print ["Testing row-pick for" n: random 100 "runs"] loop n [ test-code compose [row-pick test-table (random 1024)] ] print "On Memory low-level functions test - END" print "*********************************************" -- which seems to produce reasonable output. [TO BE CONTINUED]

 [2/4] from: petr:krenzelok:trz:cz at: 19-Jan-2002 17:23


Well, let's say that I am after simple db system like you created. But - I do have mental conflict with "in-memory" - What do I not understand is - when is status of db written to the disk? Apps tend to crash! If we will not have enough granularity for 'commit-db-to-disk, it will not be good ... -pekr-

 [3/4] from: g:santilli:tiscalinet:it at: 19-Jan-2002 18:39


Trying out Phil's mailer... :-)
>Well, let's say that I am after simple db system like you created. But - >I do have mental conflict with "in-memory" - What do I not understand is
In-memory tables are meant to be temporary. Disk tables will be implemented soon. :-) Regards, Gabriele.

 [4/4] from: chalz:earthlink at: 21-Jan-2002 0:25


A system I'm sure not many of you are very familiar with - MOO - has similar issues. Basically, it's another form of a MUD (multi-user dungeons/domains/etc - text-based multi-user gaming environment) which deals more with programming than gaming. In any event, the entire database file - which includes all code, 'rooms', players, etc - is loaded into memory at boot. The admin defines a certain 'checkpoint interval', say 3600 seconds (1 hour), after which a copy of the database is actually made in RAM, but locked (the primary still runs), and is written to disk (usually a file.db.new). It's not always perfect (of course). But, that's how they deal with it (granted the base system is probably around a decade old..). Depending upon system volatility and amount of data transfer and database size, you would need to alter the saving times, or even break the db into multiple files with a single prime 'index', so to speak, to keep in RAM. Err, course, these are comments from someone who's never done any actual DB coding.. *blushes* Just seem like semi-obvious solutions.