File: DOC.html

package info (click to toggle)
arb 6.0.6-8
  • links: PTS, VCS
  • area: non-free
  • in suites: sid, trixie
  • size: 66,204 kB
  • sloc: ansic: 394,911; cpp: 250,290; makefile: 19,644; sh: 15,879; perl: 10,473; fortran: 6,019; ruby: 683; xml: 503; python: 53; awk: 32
file content (543 lines) | stat: -rw-r--r-- 17,942 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543


ARB_DB

Basic idea:

	All data is stored hierarchically in database elements.

	A database element is a small structure which stores:
		- key
		- type	(integer/string...)
		- it's value
		- last modification time
		- access rights
		...

	A value itself might be a set of database elements.

	There are 10 basic data types:
	Type		C/C++ enum	PERL_NAME
	----------------------------------------------------------------
	String		GB_STRING	STRING	// Null terminated string
	Integer		GB_INT		INT	// 32 bit integer
	Float		GB_FLOAT	FLOAT	// real number
	BitString	GB_BITS		BITS	// any bitstring
	Integer String	GB_INTS		INTS	// array of integer
	Container	GB_DB		CONTAINER // a set of other elements


	****************************** Example 1 ***************

	Let's say we want to store the following key value pairs in the
	database:
		name	niels
		tel	37543345
		sex	male
		age	40

	So all we have to do is to create 4 database elements of type
	STRING and store the data into it:

		$gb_main = ARB::open("new_db.arb","wc");	// create new db
				// we are operating
				// in a multi user env., so we have to
				// get exclusive rights to the server:
		ARB::begin_transaction($gb_main);
				// create a dbelem key = "name"
				//			type = "STRING"
		$gb_name = ARB::create($gb_main,"name","STRING");
				// and store a value in the dbelem
		$error = ARB:write_string($gb_name,"niels");
			...
			...
		ARB:commit_transaction($gb_main);	// everything is ok
		$error = ARB::save($gb_main,"new_db.arb", "a");	// save in ascii format

	***************************** END 1 *********************


	What has been done:

		The first argument of nearly all ARB-Database (ARBDB) functions
		is an existing database element.
		You may change or read this element or use it to find or
		create other elements.

		First we create a new database "new_db.arb".
		ARB::open returns the root element of the database.
		Before we can actually read or write to it we have to
		get exclusive rights by calling
			GB_begin_transaction( root_element_of_database );
		To make all changes to the database persistent we have
		to call GB_commit_transaction, or if we want to undo all
		recent changes GB_abort_transaction.
		Because the root node of the database is always a container
		we can simply add new items to it.


	****************************** Example 2 ***************

	We have the same situation as in Example 1 but we want to store
	the name, tel .. of different persons in the database.

	So we simply store the person's data not in the root container,
	but in a person container.

		$gb_main = ....
		ARB::begin_transaction($gb_main);

		for all persons do {
			$gb_person = ARB::create_container($gb_main,"person");
			$gb_name = ARB::create($gb_person,"name","STRING");
			$error = ARB:write_string($gb_name,"name of p");
			if ($error) .....
			$gb_tel = ARB::create($gb_person,"tel", STRING);
			$error = ARB:write_string($gb_tel,"telnr of person");
		}
		commit and save

	******************************* END 2 ***************************

	What's new in the last example:

		We created sub containers for each person. All this
		have the key 'person', so in this case the key is really
		useless. Some people might think that it would be much
		better to give each container the name of the person.
		But that would limit you to search for only one field.
		So we decided not to index the keys of the database
		elements but their values. So you should not use the
		key for indexing.


Searching the database:
	There are three main ways to find your data:

		1. Use the key of the elements:
			This is good if all your keys are unique in
			a container and if there are only a few elements
			in a container.

		2. Use the value of the elements:
			This works like grep in a filesystem. Go through
			all elements and  inspect the value.
			This can be indexed, and is therefor much faster
			and more flexible than the search by key method.

		3. Walk through the database by hand:
			All elements within one container are stored as
			a linked list. A small loop allows you to create
			any user defined query

	All searching is done by two functions:
		find and search
	Both functions start the search at a user defined database elem
	(first argument).

	ARB::search is used, if all keys in a container are unique.
	example:

	$gb_searched = ARB:search($gb_start,"key1","none");
		searches in the container $gb_start for an element with
		the key 'key1'

	$gb_searched = ARB:search($gb_start,"key1/key2","none");
		searches a container $gb_h with key 'key1' in $gb_start
		and if found continues searching in $gb_h for an element
		with key 'key2'

	The last parameter enables ARB::search to create an element if it
	has not found any. To do this simply enter the type of the new
	element as the third argument. This is really usefull, if you want
	to store information in an existing database and you do not know
	whether an element exists already or not.


	ARB::find is used if not all keys are unique

	Like ARB::search it starts the search at a given element.
	It's basic syntax looks like this:

	ARB::find($gb_start_point, "[opt key]", "[opt value]", "mode");
		where mode can be:	"this"
					"down"
					"down_2"
					"this_next"
					"down_next"

	if "[opt key]" != "" than look only for items with that key
	if "[opt value]" != "" than return only those items which value
			mach the "[opt value]"
		Any '*' maches any number of characters
		Any '?' maches exactly one character
		the rest maches itself

	If opt key is the searched key and opt value == "" and mode ==
	"down" than ARB::find will behave like ARB::search.

	mode indicates the direction of the search:
	"down"	 means that $gb_start_point is a container and it
		looks for an element in that container
	"down_2" means that $gb_start_point is a container and all its
		elements are containers and it looks for elements in
		the subcontainers of $gb_start_point
	"this"	forces ARB::search to look for a brother
		of $gb_start_point.
	"this_next" continues a search started by mode == "down",
		The first parameter should be the last hit
	"down_next" continues a search started by mode == "down_2",
		The first parameter should be the father of the last hit.
		To get the father of an element call
			ARB::get_father($gb_elem);



	****************************** Example 3 ***************
	Let's find Niels in our database from example 2
	and print his data on the screen


	....
			// find an element which holds niels name
	$gb_niels_name = ARB::find($gb_main,"name","niels","down_2");
			// We want the container for niels not just his name
	$gb_niels = ARB::get_father($gb_niels_name);
			// lets loop through everything
	$gb_any = ARB::find($gb_niels,"","",down_level);
	while ($gb_any) {
			// We know that we have only strings, so this is
save
			// Just read the value
		$value = ARB::read_string($gb_any);
			// and we need the key
		$key = ARB::read_key($gb_any);
		print "$key:	$value\n";
			// get the next element
		$gb_any = ARB::find($gb_any,"","","this_next");
	}
	...


***************************** All the functions ***************

Now the rest is really trivial: only a lot of functions

	Some name conventions:
		$gb_xxx	indicates are variable which is a database
			element
		$gb_cxxx is any container
		$gb_main is always the root element
		$error is an error string



$gb_main = ARB::open("path of existing or new database.arb",flags)
	if "path of existing or new database.arb" contains a ':'
	character, then ARB looks for a server instead of a file.
		path syntax:	hostname:tcpnr		// network mode
				:path_of_unix_socket	// unix socket
				:			// default socket

	flags is a string of characters:
		r		read existing database
		w		database should be writeable
		c		create a new one if read failed
		-> r		reads a database
		-> rwc		reads or creates a database
		-> wc		always creates a new one


$error = ARB::save($gb_main,"path of the database",mode)
	mode
		a		ascii format
		b		binary format
	Only if you have opened a database on a file you are allowed to
	save it, otherwise the server has to do it.
	You may not change the path of the database, it is used
	for security. If you want to save the database to a new
	file use:

$error = ARB::save_as($gb_main,"path of the database",mode)


$error = ARB::save_quick($gb_main,"existing path of the database");
	Save all changes to a file "xxxx.quickX" where X is an
	autoincremented number between 0 and 7

$error = ARB::save_quick_as($gb_main,"new path");
	Fake an existing database by create a symbolic link and
	then call ARB::save_quick

$error = ARB::close($gb_main);
	You should be polite to your server and say good bye, so
	please call this function just before you exit.
	Nothing serious will happen if you forget to call it.


$error = ARB::begin_transaction($gb_main);
	Get the exclusive read and write rights from the server
$error = ARB::abort_transaction($gb_main);
	Undo everything since the last begin_transaction
$error = ARB::commit_transaction($gb_main);
	Write all data to the server and give the database rights
	back to other users

$error = ARB::push_transaction($gb_main);
	Increments an internal counter. If the counter was previously
	0 then calls begin_transaction. This is usefull when working
	in a subroutine and not knowing whether your calling function
	had opened a transaction already.
$error = ARB::pop_transaction($gb_main);
	Decrements the internal counter. If the counter gets zero,
	commit a transaction.


****************** Now the following functions assume that you have
	began a transaction ***************************

*************************** error handling ********************
Most of the functions return an optional error string if there have
been a problem. If a function do not return a error string but
for example a database element, you may get the error string by
	calling ARB::get_error()

example:
	$gb_main = ARB::open("Idonotexist","rw");
	if (! $gb_main ) $error = ARB::get_error();

**************************** find and search entries ***********

$gb_xxx = ARB::search($gb_start_search_point,"path/in/the/database",
		"TYPE_OF_ELEMENT_YOU_WANT_CREATE/none"
	search a database element if all keys are unique

$gb_xxx = ARB::find($gb_start_search_point, "[key]", "[value]",
	"search_mode"


************************** create new entries ***************

$gb_new_entry = ARB::create($gb_cxx, "key", "type");
	creates a new element of type "type" within $gb_cxx

$gb_new_container = ARB::create_container($gb_cxx,"key");
	create a new container within $gb_cxx

************************* read entries *******************
	// simple types
$val = ARB::read_byte($gb_xxx);
$val = ARB::read_int($gb_xxx);
$val = ARB::read_float($gb_xxx);
	// array types
$val = ARB::read_string($gb_xxx);	// read the value
$val = ARB::read_bytes($gb_xxx);	// may contain \0 characters
$val = ARB::read_ints_using_index($gb_xx, "index");
					// read the integer #index of an
					// integer array
$val = ARB::read_floats_using_index($gb_xxx, "index");

$val = ARB::read_count($gb_xxx);	// get the size of the array

$val = ARB::read_as_string($gb_xxx);	// read and convert to string

$val = ARB::read_bits($gb_xxx,char_0,char_1);
	convert a bit array into a string,
	a '0' will be converted into char_0
	a '1' into char_1

	eg: ARB:read_bits($gb_xxx, "-", "+" ); returns a '-' '+' string


************************* write entries *******************

$error = ARB::write_int($gb_xxx, "value");	// write the value
$error = ARB::write_float($gb_xxx, "value");	// write the value
$error = ARB::write_byte($gb_xxx, "value");	// write the value

$error = ARB::write_bytes($gb_xxx, "value", len);// write array of bytes
$error = ARB::write_string($gb_xxx, "value");	// write the value
$error = ARB::write_bits($gb_xxx, "value", char_0); // convert a string
				// into bitarray, all characters !=
				// char_0 will converted to 1 else 0

$error = ARB::write_as_string($gb_xxx); try to interpret the value and
				// convert it automatically to the right
				// format

If you write to an element and you do not change the value,
the element thinks, that you have done nothing, and no
element pending events are called, and the modification time is not
changed. If you want to force to change the element, call

$error = ARB::touch($gb_xxx);

******************************* etc entries ****************

$error = ARB::delete($gb_xxx);
	deletes an element or a container and it's subelements

$error = ARB::copy($gb_destination, $gb_source);
	copy's the value from source to destination.
	does not create a new element.
	the type of $gb_destination must be the type of $gb_source
	if type == "CONTAINER" than all subelements are copied

************************ security levels **********************

each database element has three security levels:
	read write and delete
each level's value is between 0 and 7

$val = ARB::read_security_read($gb_xxx);
$val = ARB::read_security_write($gb_xxx);
$val = ARB::read_security_delete($gb_xxx);

$error = ARB::write_security_read($gb_xxx, "val");
$error = ARB::write_security_write($gb_xxx, "val");
$error = ARB::write_security_delete($gb_xxx, "val");

to change any element, the users security level must be greater or
equal the elements level. To change the users level call:

$error        = ARB::change_my_security($gb_main,"level","passwd");
	passwd is not in use yet


*********************** additional element information ***********

$type = ARB::read_type($gb_xxx);
	gets the type of a database elem: "INT" "STRING" "CONTAINER" ....

$key = ARB::read_key($gb_xxx);
	read the key of a database elem:

$clock = ARB::read_clock($gb_xxx);
	gets the last modification time of an entry.
	The modification time of a container is always greater or equal
	then the modification time of it's subelements.
	The clock counts transactions, not seconds


$error = ARB::set_temporary($gb_xxx);
	Marks a field in the database as a temporary field.
	That means that this field is never saved to a file.
$error = ARB::clear_temporary($gb_xxx);
	Clears tmp flag

$error = ARB::write_flag($gb_xxx, bool);
	Sets or clears a flag in the database,
	There are functions to quickly find all flagged == marked
	entries

$gb_xxx = ARB::first_marked($gb_cxx);
	finds the first flagged element in a container

$gb_xxx = ARB::next_marked($gb_xxx);
	gets the next flagged item

$count = ARB::number_of_marked_subentries($gb_cxxx);
	adds all flags of direct subentries within $gb_cxxx

$error = ARB::write_usr_public($gb_xxx, value);
	Each element has 8 free public bits
	public means that all clients share the same bits

$value = ARB::read_usr_public($gb_xxx);


$error = ARB::write_usr_private($gb_xxx, value);
	Each element has 8 free private bits
	private means each database client has it's own bits
$value = ARB::read_usr_private($gb_xxx);


************************** ETC ************************

$error = ARB::release($gb_xxx);
	By default all clients cache all data which has been searched,
	read or modified.
	If you want to get rid of some cached items you may call
	ARB::release, which frees all data below $gb_xxx.
	Warning: All database elements, which are a subentry of $gb_xxx
	will be temporary lost. You have to search or find them again.


$error = ARB::add_callback($gb_xxx, function_name, clientdata);
	Adds a callback to a database element.
	Every time you call begin_transaction and any other client
	has changed this database element, your function_name is called
	Every time you call commit_transaction and you have made
	changed to this item, your function_name is called,

	function_name is a function with the following parameters:

	func($gb_changed_element, clientdata, "DELETED/CHANGED"
		A "DELETED" value in the third argument means that
		the element had been deleted
		A "CHANGED" value indicate only a change.

$error = ARB::remove_callback($gb_xxx, function_name);
	remove a callback


$error = ARB::create_index($gb_cxx, "key", estimated_size);
	If you call ARB::find with mode "down_2" or "this_next"
	very often on a huge database you may create an index.
	estimated_size is the estimated number of items which should
	be indexed.
	In the current version we are using a hash mechanism to index
	the elements. Only strings can be indexed.

$error = ARB::undo($gb_main, "UNDO"/"REDO");
	undo oder redo the database.
	Should not be called within a running transaction

$info = ARB::undo_info($gb_main, "UNDO"/"REDO");
	Should give you a short information about the next undo/redo

$error = ARB::set_undo_mem($gb_main, size_in_bytes);
	sets the amount of memory used to store undo values

$time = ARB::last_saved_clock($gb_main);
	transaction number when the database was last saved
	Can only be called from the server program

$time = ARB::last_saved_time($gb_main);
	the same but in seconds after 1 Jan 0:00 1970

$error = ARB::set_cache_size($gb_main, "size_in_bytes");
	ARB uses datacompression for long strings. If some strings
	are used very intensely the program may slow down.
	Therefor a small cache is used and it's size can be set
	by this function. If you are working with sequences, a value
	of 1 or 2 meg seems reasonable


$error = ARB::check_key("key");
	checks "key" is a valid key

************************* Creating a server ******************

$error = ARB::sopen("socketid",timeout_in_millisec, $gb_main);
	serves $gb_main for other clients.
	syntax of "socketid":
		host:tcpnr
		:/path/of/unix/socket
		:			// default unix socket

	prepares the database to be served. timeout is not used now
	but later in:

$error = ARB::accept_calls($gb_main);
	Watch your socket timeout_in_millisec for any clients, who need
	help

$error = ARB::shutdown($gb_main);
	shutdown the server

$clients = ARB::read_clients($gb_main)
	Get the number of clients using this server.
	if $clients == -1 than I'm a client no server
	So this can be used to check wether I'm a client or server