source: tags/ms_r16q3/PERL2ARB/DOC.html

Last change on this file was 12889, checked in by westram, 10 years ago
  • ':' → '::'
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.5 KB
Line 
1
2
3ARB_DB
4
5Basic idea:
6
7        All data is stored hierarchically in database elements.
8
9        A database element is a small structure which stores:
10                - key
11                - type  (integer/string...)
12                - it's value
13                - last modification time
14                - access rights
15                ...
16
17        A value itself might be a set of database elements.
18
19        There are 10 basic data types:
20        Type            C/C++ enum      PERL_NAME
21        ----------------------------------------------------------------
22        String          GB_STRING       STRING  // Null terminated string
23        Integer         GB_INT          INT     // 32 bit integer
24        Float           GB_FLOAT        FLOAT   // real number
25        BitString       GB_BITS         BITS    // any bitstring
26        Integer String  GB_INTS         INTS    // array of integer
27        Container       GB_DB           CONTAINER // a set of other elements
28
29
30        ****************************** Example 1 ***************
31
32        Let's say we want to store the following key value pairs in the
33        database:
34                name    niels
35                tel     37543345
36                sex     male
37                age     40
38
39        So all we have to do is to create 4 database elements of type
40        STRING and store the data into it:
41
42                $gb_main = ARB::open("new_db.arb","wc");        // create new db
43                                // we are operating
44                                // in a multi user env., so we have to
45                                // get exclusive rights to the server:
46                ARB::begin_transaction($gb_main);
47                                // create a dbelem key = "name"
48                                //                      type = "STRING"
49                $gb_name = ARB::create($gb_main,"name","STRING");
50                                // and store a value in the dbelem
51                $error = ARB::write_string($gb_name,"niels");
52                        ...
53                        ...
54                ARB::commit_transaction($gb_main);      // everything is ok
55                $error = ARB::save($gb_main,"new_db.arb", "a"); // save in ascii format
56
57        ***************************** END 1 *********************
58
59
60        What has been done:
61
62                The first argument of nearly all ARB-Database (ARBDB) functions
63                is an existing database element.
64                You may change or read this element or use it to find or
65                create other elements.
66
67                First we create a new database "new_db.arb".
68                ARB::open returns the root element of the database.
69                Before we can actually read or write to it we have to
70                get exclusive rights by calling
71                        GB_begin_transaction( root_element_of_database );
72                To make all changes to the database persistent we have
73                to call GB_commit_transaction, or if we want to undo all
74                recent changes GB_abort_transaction.
75                Because the root node of the database is always a container
76                we can simply add new items to it.
77
78
79        ****************************** Example 2 ***************
80
81        We have the same situation as in Example 1 but we want to store
82        the name, tel .. of different persons in the database.
83
84        So we simply store the person's data not in the root container,
85        but in a person container.
86
87                $gb_main = ....
88                ARB::begin_transaction($gb_main);
89
90                for all persons do {
91                        $gb_person = ARB::create_container($gb_main,"person");
92                        $gb_name = ARB::create($gb_person,"name","STRING");
93                        $error = ARB::write_string($gb_name,"name of p");
94                        if ($error) .....
95                        $gb_tel = ARB::create($gb_person,"tel", STRING);
96                        $error = ARB::write_string($gb_tel,"telnr of person");
97                }
98                commit and save
99
100        ******************************* END 2 ***************************
101
102        What's new in the last example:
103
104                We created sub containers for each person. All this
105                have the key 'person', so in this case the key is really
106                useless. Some people might think that it would be much
107                better to give each container the name of the person.
108                But that would limit you to search for only one field.
109                So we decided not to index the keys of the database
110                elements but their values. So you should not use the
111                key for indexing.
112
113
114Searching the database:
115        There are three main ways to find your data:
116
117                1. Use the key of the elements:
118                        This is good if all your keys are unique in
119                        a container and if there are only a few elements
120                        in a container.
121
122                2. Use the value of the elements:
123                        This works like grep in a filesystem. Go through
124                        all elements and  inspect the value.
125                        This can be indexed, and is therefor much faster
126                        and more flexible than the search by key method.
127
128                3. Walk through the database by hand:
129                        All elements within one container are stored as
130                        a linked list. A small loop allows you to create
131                        any user defined query
132
133        All searching is done by two functions:
134                find and search
135        Both functions start the search at a user defined database elem
136        (first argument).
137
138        ARB::search is used, if all keys in a container are unique.
139        example:
140
141        $gb_searched = ARB::search($gb_start,"key1","none");
142                searches in the container $gb_start for an element with
143                the key 'key1'
144
145        $gb_searched = ARB::search($gb_start,"key1/key2","none");
146                searches a container $gb_h with key 'key1' in $gb_start
147                and if found continues searching in $gb_h for an element
148                with key 'key2'
149
150        The last parameter enables ARB::search to create an element if it
151        has not found any. To do this simply enter the type of the new
152        element as the third argument. This is really usefull, if you want
153        to store information in an existing database and you do not know
154        whether an element exists already or not.
155
156
157        ARB::find is used if not all keys are unique
158
159        Like ARB::search it starts the search at a given element.
160        It's basic syntax looks like this:
161
162        ARB::find($gb_start_point, "[opt key]", "[opt value]", "mode");
163                where mode can be:      "this"
164                                        "down"
165                                        "down_2"
166                                        "this_next"
167                                        "down_next"
168
169        if "[opt key]" != "" than look only for items with that key
170        if "[opt value]" != "" than return only those items which value
171                        mach the "[opt value]"
172                Any '*' maches any number of characters
173                Any '?' maches exactly one character
174                the rest maches itself
175
176        If opt key is the searched key and opt value == "" and mode ==
177        "down" than ARB::find will behave like ARB::search.
178
179        mode indicates the direction of the search:
180        "down"   means that $gb_start_point is a container and it
181                looks for an element in that container
182        "down_2" means that $gb_start_point is a container and all its
183                elements are containers and it looks for elements in
184                the subcontainers of $gb_start_point
185        "this"  forces ARB::search to look for a brother
186                of $gb_start_point.
187        "this_next" continues a search started by mode == "down",
188                The first parameter should be the last hit
189        "down_next" continues a search started by mode == "down_2",
190                The first parameter should be the father of the last hit.
191                To get the father of an element call
192                        ARB::get_father($gb_elem);
193
194
195
196        ****************************** Example 3 ***************
197        Let's find Niels in our database from example 2
198        and print his data on the screen
199
200
201        ....
202                        // find an element which holds niels name
203        $gb_niels_name = ARB::find($gb_main,"name","niels","down_2");
204                        // We want the container for niels not just his name
205        $gb_niels = ARB::get_father($gb_niels_name);
206                        // lets loop through everything
207        $gb_any = ARB::find($gb_niels,"","",down_level);
208        while ($gb_any) {
209                        // We know that we have only strings, so this is
210save
211                        // Just read the value
212                $value = ARB::read_string($gb_any);
213                        // and we need the key
214                $key = ARB::read_key($gb_any);
215                print "$key:    $value\n";
216                        // get the next element
217                $gb_any = ARB::find($gb_any,"","","this_next");
218        }
219        ...
220
221
222***************************** All the functions ***************
223
224Now the rest is really trivial: only a lot of functions
225
226        Some name conventions:
227                $gb_xxx indicates are variable which is a database
228                        element
229                $gb_cxxx is any container
230                $gb_main is always the root element
231                $error is an error string
232
233
234
235$gb_main = ARB::open("path of existing or new database.arb",flags)
236        if "path of existing or new database.arb" contains a ':'
237        character, then ARB looks for a server instead of a file.
238                path syntax:    hostname:tcpnr          // network mode
239                                :path_of_unix_socket    // unix socket
240                                :                       // default socket
241
242        flags is a string of characters:
243                r               read existing database
244                w               database should be writeable
245                c               create a new one if read failed
246                -> r            reads a database
247                -> rwc          reads or creates a database
248                -> wc           always creates a new one
249
250
251$error = ARB::save($gb_main,"path of the database",mode)
252        mode
253                a               ascii format
254                b               binary format
255        Only if you have opened a database on a file you are allowed to
256        save it, otherwise the server has to do it.
257        You may not change the path of the database, it is used
258        for security. If you want to save the database to a new
259        file use:
260
261$error = ARB::save_as($gb_main,"path of the database",mode)
262
263
264$error = ARB::save_quick($gb_main,"existing path of the database");
265        Save all changes to a file "xxxx.quickX" where X is an
266        autoincremented number between 0 and 7
267
268$error = ARB::save_quick_as($gb_main,"new path");
269        Fake an existing database by create a symbolic link and
270        then call ARB::save_quick
271
272$error = ARB::close($gb_main);
273        You should be polite to your server and say good bye, so
274        please call this function just before you exit.
275        Nothing serious will happen if you forget to call it.
276
277
278$error = ARB::begin_transaction($gb_main);
279        Get the exclusive read and write rights from the server
280$error = ARB::abort_transaction($gb_main);
281        Undo everything since the last begin_transaction
282$error = ARB::commit_transaction($gb_main);
283        Write all data to the server and give the database rights
284        back to other users
285
286$error = ARB::push_transaction($gb_main);
287        Increments an internal counter. If the counter was previously
288        0 then calls begin_transaction. This is usefull when working
289        in a subroutine and not knowing whether your calling function
290        had opened a transaction already.
291$error = ARB::pop_transaction($gb_main);
292        Decrements the internal counter. If the counter gets zero,
293        commit a transaction.
294
295
296****************** Now the following functions assume that you have
297        began a transaction ***************************
298
299*************************** error handling ********************
300Most of the functions return an optional error string if there have
301been a problem. If a function do not return a error string but
302for example a database element, you may get the error string by
303        calling ARB::get_error()
304
305example:
306        $gb_main = ARB::open("Idonotexist","rw");
307        if (! $gb_main ) $error = ARB::get_error();
308
309**************************** find and search entries ***********
310
311$gb_xxx = ARB::search($gb_start_search_point,"path/in/the/database",
312                "TYPE_OF_ELEMENT_YOU_WANT_CREATE/none"
313        search a database element if all keys are unique
314
315$gb_xxx = ARB::find($gb_start_search_point, "[key]", "[value]",
316        "search_mode"
317
318
319************************** create new entries ***************
320
321$gb_new_entry = ARB::create($gb_cxx, "key", "type");
322        creates a new element of type "type" within $gb_cxx
323
324$gb_new_container = ARB::create_container($gb_cxx,"key");
325        create a new container within $gb_cxx
326
327************************* read entries *******************
328        // simple types
329$val = ARB::read_byte($gb_xxx);
330$val = ARB::read_int($gb_xxx);
331$val = ARB::read_float($gb_xxx);
332        // array types
333$val = ARB::read_string($gb_xxx);       // read the value
334$val = ARB::read_bytes($gb_xxx);        // may contain \0 characters
335$val = ARB::read_ints_using_index($gb_xx, "index");
336                                        // read the integer #index of an
337                                        // integer array
338$val = ARB::read_floats_using_index($gb_xxx, "index");
339
340$val = ARB::read_count($gb_xxx);        // get the size of the array
341
342$val = ARB::read_as_string($gb_xxx);    // read and convert to string
343
344$val = ARB::read_bits($gb_xxx,char_0,char_1);
345        convert a bit array into a string,
346        a '0' will be converted into char_0
347        a '1' into char_1
348
349        eg: ARB::read_bits($gb_xxx, "-", "+" ); returns a '-' '+' string
350
351
352************************* write entries *******************
353
354$error = ARB::write_int($gb_xxx, "value");      // write the value
355$error = ARB::write_float($gb_xxx, "value");    // write the value
356$error = ARB::write_byte($gb_xxx, "value");     // write the value
357
358$error = ARB::write_bytes($gb_xxx, "value", len);// write array of bytes
359$error = ARB::write_string($gb_xxx, "value");   // write the value
360$error = ARB::write_bits($gb_xxx, "value", char_0); // convert a string
361                                // into bitarray, all characters !=
362                                // char_0 will converted to 1 else 0
363
364$error = ARB::write_as_string($gb_xxx); try to interpret the value and
365                                // convert it automatically to the right
366                                // format
367
368If you write to an element and you do not change the value,
369the element thinks, that you have done nothing, and no
370element pending events are called, and the modification time is not
371changed. If you want to force to change the element, call
372
373$error = ARB::touch($gb_xxx);
374
375******************************* etc entries ****************
376
377$error = ARB::delete($gb_xxx);
378        deletes an element or a container and it's subelements
379
380$error = ARB::copy($gb_destination, $gb_source);
381        copy's the value from source to destination.
382        does not create a new element.
383        the type of $gb_destination must be the type of $gb_source
384        if type == "CONTAINER" than all subelements are copied
385
386************************ security levels **********************
387
388each database element has three security levels:
389        read write and delete
390each level's value is between 0 and 7
391
392$val = ARB::read_security_read($gb_xxx);
393$val = ARB::read_security_write($gb_xxx);
394$val = ARB::read_security_delete($gb_xxx);
395
396$error = ARB::write_security_read($gb_xxx, "val");
397$error = ARB::write_security_write($gb_xxx, "val");
398$error = ARB::write_security_delete($gb_xxx, "val");
399
400to change any element, the users security level must be greater or
401equal the elements level. To change the users level call:
402
403$error        = ARB::change_my_security($gb_main,"level","passwd");
404        passwd is not in use yet
405
406
407*********************** additional element information ***********
408
409$type = ARB::read_type($gb_xxx);
410        gets the type of a database elem: "INT" "STRING" "CONTAINER" ....
411
412$key = ARB::read_key($gb_xxx);
413        read the key of a database elem:
414
415$clock = ARB::read_clock($gb_xxx);
416        gets the last modification time of an entry.
417        The modification time of a container is always greater or equal
418        then the modification time of it's subelements.
419        The clock counts transactions, not seconds
420
421
422$error = ARB::set_temporary($gb_xxx);
423        Marks a field in the database as a temporary field.
424        That means that this field is never saved to a file.
425$error = ARB::clear_temporary($gb_xxx);
426        Clears tmp flag
427
428$error = ARB::write_flag($gb_xxx, bool);
429        Sets or clears a flag in the database,
430        There are functions to quickly find all flagged == marked
431        entries
432
433$gb_xxx = ARB::first_marked($gb_cxx);
434        finds the first flagged element in a container
435
436$gb_xxx = ARB::next_marked($gb_xxx);
437        gets the next flagged item
438
439$count = ARB::number_of_marked_subentries($gb_cxxx);
440        adds all flags of direct subentries within $gb_cxxx
441
442$error = ARB::write_usr_public($gb_xxx, value);
443        Each element has 8 free public bits
444        public means that all clients share the same bits
445
446$value = ARB::read_usr_public($gb_xxx);
447
448
449$error = ARB::write_usr_private($gb_xxx, value);
450        Each element has 8 free private bits
451        private means each database client has it's own bits
452$value = ARB::read_usr_private($gb_xxx);
453
454
455************************** ETC ************************
456
457$error = ARB::release($gb_xxx);
458        By default all clients cache all data which has been searched,
459        read or modified.
460        If you want to get rid of some cached items you may call
461        ARB::release, which frees all data below $gb_xxx.
462        Warning: All database elements, which are a subentry of $gb_xxx
463        will be temporary lost. You have to search or find them again.
464
465
466$error = ARB::add_callback($gb_xxx, function_name, clientdata);
467        Adds a callback to a database element.
468        Every time you call begin_transaction and any other client
469        has changed this database element, your function_name is called
470        Every time you call commit_transaction and you have made
471        changed to this item, your function_name is called,
472
473        function_name is a function with the following parameters:
474
475        func($gb_changed_element, clientdata, "DELETED/CHANGED"
476                A "DELETED" value in the third argument means that
477                the element had been deleted
478                A "CHANGED" value indicate only a change.
479
480$error = ARB::remove_callback($gb_xxx, function_name);
481        remove a callback
482
483
484$error = ARB::create_index($gb_cxx, "key", estimated_size);
485        If you call ARB::find with mode "down_2" or "this_next"
486        very often on a huge database you may create an index.
487        estimated_size is the estimated number of items which should
488        be indexed.
489        In the current version we are using a hash mechanism to index
490        the elements. Only strings can be indexed.
491
492$error = ARB::undo($gb_main, "UNDO"/"REDO");
493        undo oder redo the database.
494        Should not be called within a running transaction
495
496$info = ARB::undo_info($gb_main, "UNDO"/"REDO");
497        Should give you a short information about the next undo/redo
498
499$error = ARB::set_undo_mem($gb_main, size_in_bytes);
500        sets the amount of memory used to store undo values
501
502$time = ARB::last_saved_clock($gb_main);
503        transaction number when the database was last saved
504        Can only be called from the server program
505
506$time = ARB::last_saved_time($gb_main);
507        the same but in seconds after 1 Jan 0:00 1970
508
509$error = ARB::set_cache_size($gb_main, "size_in_bytes");
510        ARB uses datacompression for long strings. If some strings
511        are used very intensely the program may slow down.
512        Therefor a small cache is used and it's size can be set
513        by this function. If you are working with sequences, a value
514        of 1 or 2 meg seems reasonable
515
516
517$error = ARB::check_key("key");
518        checks "key" is a valid key
519
520************************* Creating a server ******************
521
522$error = ARB::sopen("socketid",timeout_in_millisec, $gb_main);
523        serves $gb_main for other clients.
524        syntax of "socketid":
525                host:tcpnr
526                :/path/of/unix/socket
527                :                       // default unix socket
528
529        prepares the database to be served. timeout is not used now
530        but later in:
531
532$error = ARB::accept_calls($gb_main);
533        Watch your socket timeout_in_millisec for any clients, who need
534        help
535
536$error = ARB::shutdown($gb_main);
537        shutdown the server
538
539$clients = ARB::read_clients($gb_main)
540        Get the number of clients using this server.
541        if $clients == -1 than I'm a client no server
542        So this can be used to check wether I'm a client or server
543
Note: See TracBrowser for help on using the repository browser.