forked from elchs/LetoDBf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReadme.txt
2662 lines (2173 loc) · 161 KB
/
Readme.txt
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
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
__ __ ____ ____ __
/ / ___ / /_____ / __ \/ __ )/ _|
/ / / _ \/ __/ __ \/ / / / __ | |_
/ /___/ __/ /_/ /_/ / /_/ / /_/ /| _|
/_____/\___/\__/\____/_____/_____/ |_| ork
# Welcome to LetoDBf
Contents
--------
0. tl;dr
1. Directory structure
2. Building binaries
2.1 via hbmk2
2.2 Borland Win32 C compiler
2.3 MS Visual C compiler
2.4 Old Harbour 3.0
2.5 xHarbour
2.6 C-API library
3. Running and stopping server
3.1 the classic way for all OS
3.2 Run as Windows service
4. Server configuration
4.1 letodb.ini
4.2 Different Server setups
4.3 Authentication
4.4 Samba file service
4.5 Security
5. How to work with the letodb server
5.1 Connecting to the server from client programs
5.2 Filters and Relations
5.3 Database driver
5.4 Special Data Files in RAM
6. Variables management
7. Functions list
7.1 Connection management functions
7.2 Transaction functions
7.3 Additional functions for current workarea
7.4 Additional rdd functions
7.5 Setting client paramenter
7.6 File functions
7.7 Management functions
7.8 User account management functions
7.9 Server variable management functions
7.10 Calling udf-functions on the server
7.11 Functions for bitmap filters
8. Utils
8.1 Server Management utility
8.2 Uhura
9. Server-side functions
10 Abbreviations and remarks
11 Trouble-Shooting
A. Internals
0. tl;dr
In following chapters with many words is described the extended use of the pair:
<client> and <server>.
The <server> is an executable build with Harbour running in a network,
and <client> communicating with the server is your project linked with this library,
So you get a R-eplaceable D-atabase D-river RDD "LETO", selected after connected as default DB driver,
if not explicitely given in functions like DbUseArea(), to use a client local file with e.g, "DBFNTX".
Databases and index orders are then used by the server, the client requests the server about records
and timed caches them in client RAM for further access.
For a quick early test, Harbour users need to read chapters/ and do:
# 2.1 --> building server executable // client lib:
hbmk2 letodb[ svc ] // hbmk2 rddletoaddon
# adapt server dataroot- & log- path in bin/letodb.ini
3. --> start executable[ or service ]
check server up and working with one or more of tests examples
# 5.1 --> build your project: hbmk2 yourapp[.prg|.hbp] letodb.hbc
[ not xHarbour ] provide a copy of "tests/rddleto.txt" renamed as ".ini" along with
your executable -- adapt therein IP | DNS name of the server, or use "DETECT"
# start your app ...
# really found a left over BUG ? - try to nail it with a snippet, report !!
1. Directory structure
bin/ - server executable file
include/ - source header files
lib/ - rdd library
source/
client/ - client RDD lib sources
common/ - some common source files to server and client
server/ - server sources
3rd/ - third party source
3rd/lz4 - LZ4 compression library
tests/ - test programs, samples
utils/
manager/ - server management utilities
backup/ - demo of backup-ing a running server
uhura/ - automatic server IP detection
2. Building binaries
* This software is designed to be yourself build from sourcecode ! *
* So it is recommended to check for fresh version from download origins given below *
Get and build the fantastic Harbour:
The letodb server can be compiled only by the Harbour compiler >= V3.0.
It is strong recommended to download and build Harbour from the fresh 3.2 source:
git clone https://github.com/harbour/core.git
For this you need your C-Compiler used for Harbour in your OS search path.
Or use latest Harbour binary ( 'nightly' ) package:
https://sourceforge.net/projects/harbour-project/files/
https://github.com/vszakats/harbour-core/releases
Afterall the path to the 'hbmk2' executable is also added to OS search path list.
Follow the instructions found with Harbour.
Get latest source of LetoDBf
with GIT:
git clone https://github.com/elchs/LetoDBf.git
or as packed package at:
https://github.com/elchs/LetoDBf
ZIP: https://github.com/elchs/LetoDBf/zipball/master
TAR: https://github.com/elchs/LetoDBf/tarball/master
and change in command window into the the root directory of download package.
2.1 building letodb with hbmk2, for all C compilers
Server itself:
letodb.hbp is ready configured server for Windows and Linux daemon,
letodbsvc.hbp is ready configured server for use as Windows service.
-- Windows service hbmk2 letodbsvc
-- all other OS hbmk2 letodb
Client library:
-- all OS: hbmk2 rddleto
Recommended is to integrate LetoDbf client library into your Harbour environment as an 'addon':
-- all OS: hbmk2 rddletoaddon
If Linux user have 'installed' Harbour, you need root rights to also install LetoDBf as 'addon':
-- Linux: [ sudo ] hbmk2 rddletoaddon
Resulting server executable will be found in the "bin" directory, library will be in "lib".
In the "bin" directory is also the "letodb.ini" file to configure the server.
After successful build as 'addon', you can compile *at any place* your applications with:
hbmk2 your_application letodb.hbc
else you have to point to the "letodb.hbc", example out of a sub-directory in LetoDBf:
hbmk2 your_application ../letodb.hbc
!* If "letodb.hbc" is not used, please check section: 5.1.2 building your application *!
how to manually ensure what the "letodb.hbc" automatize.
For first testing purpose it is recommended to let the server executable remain in the "bin"
directory of your LetoDBf package. The following will just copy the executable and letodb.ini
to another place, you may know a better place for them and do that manually.
To install LetoDBf server into your OS system search paths:
-- Linux with Harbour 'installed':
sudo hbmk2 letodbaddon.hbp
-- all OS: hbmk2 letodbaddon.hbp
Then the server executable goes into the place, where the Harbour executable directory is.
In Windows the letodb.ini goes also into same place, in Linux it goes into: "/etc",
where you need admin rights to change config options.
! Installing LetoDBf needs to outcomment and adjust the <LogPath> in letodb.ini !
Use e.g. temporary directory of your OS, where normal users have write rights, e.g.: "/tmp".
Scroll down, continue to read in section: 3. Running and stopping server
2.2 Borland Win32 C++ compiler
2.3 Old MS Visual C compiler
If the above described way to compile with ".hbp" files does not work ( wrong setup ?, no hbmk2 ),
for BCC and old older MsVc exists a make_b32.bat and a make_vc.bat. Look into, adapt OS search
paths to point to Harbour and your C-compiler executable. Further important is to set:
"HB_PATH" to point to the base! directory of Harbour, e.g. "C:\harbour"
Called without argument these build the C-API client library, called with "full" as first argument
they build LetoDBf server and Harbour client library.
You will know what to do, are on your own. I use them only for sporadic compile tests.
BCC55 and maybe also newer ones have a problem with compiling LZ4 compression library, you will
get this case slower ZLib compression. This must fit together for client lib and server when you
want to use network traffic compression. It is configured by this "{!bcc}" at top in the ".hbp" files.
2.4 Old Harbour 3.0
Basically it is possible to compile and use LetoDBf with older Harbour version 3.0.
For this you have to search in above named HBP files for the line with: "#-cflag=-D__HARBOUR30__=1",
and there to remove the single character '#' at line start, which means the line is outcommented.
This should be the last solution, as you will miss some fantastic new features of Harbour 3.2 and
instead get some left and meanwhile fixed bugs.
As the hbmk2 make tool v 3.0 does not know about the "-env:" option in the HBP files, you have to set
these as environment variables. So to set Environment variables: __LZ4=yes and __PMURHASH=yes
to get defaults to use LZ4 compression and PMurHash algorithm. This is done in your terminal for
Windows with: SET ...=... and in Linux with: export ...=...
Hbmk2 3.0 does that not automatic '#include rddleto.ch' into your projects, but can be done by
by using harbour switch: "/u+rddleto.ch".
2.5 xHarbour
SERVER: the server itself must be build with Harbour, cannot be done with xHB.
Same applies for utils like console monitor.
CLIENT: client library (RDD) can be build with xHarbour, use the 'rddleto.lib.xbp' definition for
xBuilder. For Windows ( but not for XCC ), it will by default use a second thread ( without HVM ),
so the executable must be linked with a library containing '_beginthreadex()'.
cFlag define: LETO_NO_THREAD=1 set for xHB will disable this and the need for threading function,
[ C-compiler: note that xBuilder doesn't store used C-compiler -- change it on demand.
XCC: can't compile 3rd party 'lz4.c', compile it with PellesC >= 4.5 manually,
and replace it in list of files for xBuilder with resulting 'lz4.obj':
pocc.exe -Fo"obj\lz4.obj" -Ot -I"include" -I"source\3rd\lz4\lib" -I%PATH_XHB%"\include"
-I%PATH_POCC%"\Include" -I%PATH_POCC%"\include\Win" "source\3rd\lz4\lib\lz4.c"
]
DEMO: one single demo 'test_mem.exe.xbp' is designed and tested with PellesC ( POCC ) V8.0 [ >= 6.0 ]
For this lib 'crtmt.lib' is in link list, other C-compiler may replace that "crtmt.lib" with one of
their distribution ( cw32mt.lib, libcmt.lib .. )
XCC, and RDD lib with disabled thread have to remove library from list.
Same way you can build other examples "test_[func|filt|dbf|dbfe|var|file]"
YOUR APP:
like above demo: link a MultiThread C runtime lib,
#include "rddleto.ch" for each '.prg' of a xHB LetoDBf project by xHB switch: "/u+rddleto.ch".
One source file of your project, i suggest that with function main() and Leto_Connect(),
should: REQUEST LETO
(*) Codepage-names of xHB and server build with Harbour may be different, that needs to
set up a 'name translation table' -- see LETO_ADDCDPTRANSLATE()
2.6 C-API library
This is to use a part of the client library from pure C-level *only* with a C-compiler.
All Harbour RDD methods ( leto1.c ), and all relations to PRG level functions ( letomgmn.c ) are
left out for this purpose. It is build with:
hbmk2 apileto.hbp
The resulting libleto.[a|lib] is found afterwards in the lib directory.
Short examples given in: tests/c_api/*.c should give an bit experienced C-developer a quick vision.
To build the examples, use in that directory a bldc.bat [ BCC ] or a bldc.sh [ GCC ].
Adapt therein the paths to Harbour and C-compiler bin directory, call them with filename without
extension as first param, e.g.;
bldc.[bat|sh] test_dbf
Result is executed with first param IP|DNS-name of the server to connect, if not given 'localhost'
aka '127.0.0.1:2812' will be used.
Notes: the C-API lib uses Harbours' hb_xgrab[z](), hb_xrealloc() and hb_xfree(). These memory
allocations/ frees' can friendly co-exist with another memory system, but memory allocated with
one system must be free-ed by the same. Herefore a list of Harbour libs is needed for static builds,
caused by hvm.[a|lib] containing the memory functions, but also links to the other libs.
Linking to the dynmic Harbour lib would ease this very, example is outcommented in the batch files.
It is possible to execute functions at server with LetoUdf(), but herefore some basic knowledge
of handling PHB_ITEMs is needed to transmit function params to the server and to handle the received
result. Please note the second param of LetoUdf( , LETOTABLE * pTable, .. ): if not NULL, this WA
will be pre-selected at server before the remote function is executed. [ see also 4.2.1 UDF support ]
No Harbour HVM is started, so be careful calling Harbour internal functions which need such,
e.g. functions relaying on the stack of a HVM like hb_setGet..(). Also the codepage system is not
initalized -- that is by intention to keep the usage of the C-API lib a <raw> as possible.
3. Running and stopping server
Before you do so, adapt the "DataPath" in letodb.ini, the most important setting, see 4.1
If this path does not exist or is invalid, the server will not start !
If you 'installed' the server or use it as service, also outcomment and adapt the LogPath,
where the log files will go. If LogPath is not set, they go into directory of server executable.
For both directories user needs write rights granted by the OS.
3.1 the classic way for all OS
Start it, in default mode __WIN_DAEMON__ or both modes __LINUX_DAEMON__ and __CONSOLE__
start /B letodb.exe ( Windows )
./letodb ( Linux )
To shutdown the server, run the executable with the 'stop' parameter:
letodb.exe stop ( Windows )
./letodb stop ( Linux )
To reload the "letoudf.hrb" module, containing UDF server side functions, it must be in same
directory same as server executable, use the 'reload' parameter:
letodb.exe reload ( Windows )
./letodb reload ( Linux )
Above examples will use default 'letodb.ini' config file. To use an explicitely named,
add these two params: <start-command> config myini.ini
or use a third param for stop/ reload, example: ./letodb stop myini.ini
Linux: it needs a pause of 1-2 minute before you can restart server after a shutdown.
To automize that, use bash script: 'leto.sh' in "bin" directory, it will start the server
when it is again possible. It is about the time that must elapse before TCP/IP can release a
closed connection and reuse its resources. This is known as TIME_WAIT state.
Windows: above 'start /B' command to prevent a black window can be put into a '.bat' batch file.
There exists some tiny tools, aka executables to 'hidden' start another process.
( example incl. C-source found in: http://www.commandline.co.uk/chp/ ).
--> Look into letodbf.log, that server is up -- also further server related error goes here.
At same place, in 'letodbf_xx.log' error feedback of a specific connection may appear.
Both easily can be viewed with: 8.1.1 All OS console
3.2 Run as Windows@ service
For use as "Windows service" server executable must be compiled for this task, see 2.1
To install LetoDbf as service, the executable must be placed in a directory covered by the OS
system search paths to be found from any place. Then run letodb with 'install' parameter:
letodb.exe install [letodb.ini]
The 3rd param is optinonal for different config to use for multiple LetoDBf services, e.g.
running at different disk partitions.
Verify in letodbf.log that the service was successful installed and started.
To check the state of a Windows service use the GUI management for services.
Alternatively at command line can be used to start/ stop the service:
net start LetoDBf_Service
net stop LetoDBf_Service
To deinstall service again, run letodb with 'uninstall' parameter:
letodb.exe uninstall [letodb.ini]
It possible may need to restart your Windows machine. You can check beforehand if the service is
still listed in the GUI management for services, else it is not needed.
4. Server configuration
4.1 letodb.ini
In Windows environment the letodb.ini config file must be placed in directory of server executable.
In Linux the server looks for it in directory "/etc", if not found there then in the directory of
server executable.
This file is only read once with starting LetoDBf, after changes therein you have to restart the server
to let it get active.
Really important options commonly only are: DataPath, LogPath, Share_Tables, No_Save_WA.
If the server should use an existing DBF fileset, adapt 'Default_Driver' if DBFNTX was used.
Other default values in the distributed config file are choosen to satisfy most common first needs,
can be hardend and optimzed on occasion.
LetoDBf newbies now like to continue reading with section: 5. How to work with the LetoDBf server.
Currently following parameters exists ( default values are designated ).
[MAIN]
IP = - Interface given by IP address, where Letodb server listen for connections.
Empty ( default ) is recommended for intranet usage, then all interfaces
available at the computer, including the virtual 'loopback' device are used.
If set, only this interface ( given by IP address ) is used.
Unix user can alternatively use interface names like: 'eth1'
If internet is available at machine, read also section 4.5 Security
Server = - IP address used by tools like management console to find the server.
This can be, but must not be, the same as used for config option 'IP'
and is just for convenience.
Port = 2812 - Server port number, default is 2812 [ then 2813 used for second socket ]
There are two! ports used by server, this and the following number.
! You ever connect to first port number !
DataPath = - PATH to a base directory on a server with your databases,
may include also a drive letter for poor Windows systems
LogPath = - if config option <DEBUG> level is greater zero [ 0 ],
PATH to a directory (with write access) for all log files.
File letodbf.log for the main server will contain some info from settings
at server starttime, plus info about new connected and disconneted clients
No_Save_WA = 1 - server mode of internally handling database tables
1 each dbUseArea() will cause a real file open operation by the OS,
identical to what client requested, so workareas at the server are same as
at client side. [ WA number, alias, filter conditions, relations ]
0 each table is opened only one time, this workarea 'exchanged' in between client
requests. so only one connection will have access to the table at a time.
No relations active at server, Alias names at server are different from
the client.
Recommend '1' if you plan to execute functions at server side ( UDF ).
Share_Tables = 0 - other software simultanous access tables used by server,
which changes logical or physical record locking -- in dependance:
# No_Save_WA = 0
0 server open all tables in exclusive mode, what leads to
performance increase as e.g. record-/ file- locks are not applied by OS.
1 tables are opened in the same mode [shared/exclusive] as client
applications opened them, what allows LetoDB to work in coexistence with
other applications [ non LetoDB users ] simultanous on the same DBF tables.
# No_Save_WA = 1
1 physical record-/ file- locks set with the OS are viewable for other
0 only logical internally locking, don't respect other record locks
* SAMBA: *
co-work with Samba file-service needs very special treatment/ setup
and have limits of possibilities -- see chapter 4.4
Default_Driver = CDX - default RDD to open DBF tables at server, if not set explicitely in your
sourcecode with leto_DbDriver().
Possible values for config: CDX NTX
If the server is linked with rushmore index support,
CDX gets BMCDX and NTX will became BMNTX
If not set, the server by default uses CDX [ BMCDX ]
Cache_Records - The default number of records to be read into the client read cache,
used for skipping etc without new requesting the server.
Records are valid at client as long as the hotbuffer timeout.
Default is 10, minimum is 1 (slow performance), good values are 10 - 50,
theoretical ! maximum 65535. Adapt for performance in your environment.
Can be set for specific tables and occasions with leto_SetSkipBuffer().
Lock_Scheme = 0 - If > 0, extended locking scheme will be used by server.
* This is only needed, if your DBF will be greater in size as 1 GB. *
Then DB_DBFLOCK_HB32 will be used for NTX/CDX;
_or_ if set to 6, DB_DBFLOCK_CLIPPER2 for NTX, HB32 for other
_or_ if set to 2, DB_DBFLOCK_COMIX for CDX, HB32 for other
_or_ if set to 5, DB_DBFLOCK_HB64 for all.
Memo_Type = - LEAVE IT EMPTY, to get the default for the choosen option Default_Driver.
Default: FPT for DBFCDX, DBT for DBFNTX, SMT for others.
Memo_BSize = - for !expert! users !, this will change default memo blocksize
for *NEW* created DBF data tables. Before doing so, you need a lesson about.
Lower_Path = 0 - default 0: respects requested filenames case sensitive
if 1, convert all paths and filenames to lower case;
This is useful if all files at disk are in 'suggested' lower case,
but name in source-code is written in mixed or upper case,
which will fail for case sensitive 'storage' filesysten,
EnableFileFunc = 0 - if 1, using of file functions ( leto_file(), leto_ferase(),leto_frename() etc ..
is allowed. Else these functions do nothing or return .F.
EnableAnyExt = 0 - if 1, *creating* of data tables and indexes with any extention, other than
standard ( dbf,cdx,ntx ) is allowed. Else these would be rejected.
Pass_for_Login = 0 - Lowest level of password verification: after login all is allowed to all
if 1, user authentication is necessary to login to the server;
Pass_for_Manage = 0 - if 1, user authentication is necessary to use management functions,
e.g. run the monitor console [ Leto_mggetinfo() ]
Pass_for_Data = 0 - if 1, user authentication is necessary to have write access to the data;
Pass_File = leto_users - [ path + ] filename of the user database for authentication.
If no path is given, it will appear in directory of server executable
Server_User = The Unix/ Linux username from whom UID and GUI are fetched for __LINUX_DAEMON__.
Have precedence over following two options, if username is given and exists.
Server_UID = 0 The User-ID and Group-ID for the Linux server to run as daemon.
Server_GID = 0 Your DBF tables will get this IDs, important for choosing the correct access rights.
Default is empty, then this will be the U-ID and G-ID who started the server.
Max_Vars_Number = 1000 - Maximum number of shared variables
Max_Var_Size = 67108864 - Maximim size in sum of all text/ array variables, default 64 MB.
A single text/ array variable is allowed to be a quarter of that ( 16 MB )
Be very carefull with thoughtless increasing this value to much bigger sizes,
as the server will need at least 4 times of that value as RAM.
Theoretical! maximum for a single! item is ~ 4 GB, then your server will need
to have 64! GB!! RAM. [ NOT tested ! :-) ]
Trigger = cFuncName - Server side trigger function for *every* table. ! USE WITH SPECIAL CARE !
If given, this trigger function is executed for *all* opened WAs for specific
actions like record append, update, ...
Function <cFuncName> must be known at server, and can be a HRB loaded UDF
function. It receives 4 params: nEvent, nArea, nFieldPos, xTrigVa;
where nFieldPos and xTrigVal are only filled for events EVENT_PUT and EVENT_GET.
( see an example of "Leto_Trigger" in: tests/letoudf.prg )
Tables_Max = 999 - Number of *MAXIMUM* designated DBF tables handled by server,
for server mode No_Save_WA == 0 this are physical DBF tables,
for server mode No_Save_WA == 1 this are DBF tables opened by all users.
This number can *not* be increased during runtime of server.
Theoretically maximum value: 999999, minimum: >= 99
Increase default value big enough to your needs,
Example for No_Save_WA == 0: 2 * physical existing DBF
Example for No_Save_WA == 1: Users_Max * physical existing DBF
( Maximum limit per one single user connection is about ~ 60000. )
** OS may limit the open files per 'user', this case server itself **
[ /etc/security/limits.conf; ...\CurrentControlSet\services\Tcpip\Parameters ]
Users_Max = 99 - Number of *MAXIMUM* designated users. do not set too low.
This number can *not* be increased during runtime of server.
Theoretically maximum value: 65534. minimum is >= 9
Increase default value big enough to your needs, example two times as actually
users, but do not exaggerate.
Debug = 1 - Debug level, default: 1 --> only minor information about login/ logout of
connections is written into letodbf.log
0 = none debugging messages -- notice that real errors are always logged.
The greater the the value, the more information is written.
A value >= 15 will include partly communication traffic to server,
with a value > 20 the full communication protocol is logged.
!! USE WITH CARE !!, the log files can get very quick VERY BIG.
It can be changed 'on the fly' for critcal sections with new
RDDI_DEBUGLEVEL -- see 7.5
ONLY increase value in case of problems, to trace what happened at server,
and the actions from client. Each connection will get an own log file with
connection-ID as file extension; new created when a connection starts.
HardCommit = 0 - if 0, SET HARDCOMMIT OFF, this is now DEFAULT.
It is recommended for UNSTABLE running server to set it to <1>,
which means that each change at data tables are immedeate written to
harddrive bypassing the OS cache.
Expect significant reduced performance with setting '1'.
ForceOpt = 0 - _SET_FORCEOPT setting
Allow_Udf = 0 - security setting, DEFAULT is ! NOT ! to allow the use of
loaded UserDefinedFunction for remote execution at server.
With value 0 even a Leto_UDFExist() will deny to answer.
Set to 1 to use UDF functionality on LetoDB server.
0 will disable that possibility.
TimeOut = -1 - Connection timeout in seconds, -1 means infinite wait.
This timeout determine, how long a write to network/ wait for requested workarea
will wait to succeed, before the thread for the connection give up.
If used: Zombie_Check, this value shell be shorter than that.
Zombie_Check = 0 - Time in seconds, that a client must be quiet ( no activity ), before
a 'are you healthy' query (ping) is send from server, to verify it's not a
dead/ unplugged connection. ! Application must be linked multi-thread ( '-mt' ) !,
else these checks cannot be done.
As 3 times for a given interval a check is done, a zombie can be 1/3 time
longer 'dead', e.g. 60 ==> max. 80 seconds 'dead' before detected.
Such connection will be shut down, opened files and locks are reset-ed.
If set to 0 [ default ], these checks are diabled.
;BC_Services = letodb; - build-in 'Uhura' BroadCast servive, default <off> as outcommented:
it activates BC BroadCast response service for list of 'service-names',
each name to end with an ';' -- a request will get back the server-IP
;BC_Interface = eth2 - experimental/ Linux: use only specific interface for response
;BC_Port = 2812 - specify different than default port for UDP BC interfaces,
by default the same port as configured for TCP port
;IP_SPACE = - like a firewall: it contains an lefthand IP-address part which must be
found in the IP which want to connect to the server.
Multiple parts can be defined, delimited by ';' ( no extra spaces )
Example for two NIC intranet: IP_SPACE = 192.168.0.;192.168.1.;
;SMB_SERVER = 0 - set this to 1 for concurrency usage with Samba, and read 4.4 Samba
;SMB_PATH = - in conjunction with SMB_SERVER = 1, for both options read further
in 4.4 Samba file service
;SVC_NAME = - useable for Windows service to set a different service-name for
multiple running server at same machine, default is "LetoDBf_Service";
commonly used together with different filename for configuration
;Crypt_Traffic = - if set to '1' [ default = 0 ] it enforces network traffic encryption,
aka all connections not using encryption are blocked/ shut down.
A manually used Leto_ToggleZip() will be without effect, aka compression
with encryption can not be deactivated.
;Backup_Info = ... It contains a string with comma separated lines to be shown in the 'backup-box'
at clients, when function: Leto_LockLock() is executed.
Default string: BACK-UP,WAITING,ESC-> GO ,ESC->QUIT
shows 3 lines, and last two lines are for complain/ final mode
A not out-commented option with explicitely empty string activates
'old-style' behaviour for Leto_LockLock().
;Data_LogFile = to activate a data-change logging into the given filename.
If no path is given or the path starts with "./" the place is at "DataPath"
or at given sub-directory to that, else a given path is treated as absolute
path possible located at another storage. During server startup a path to
the file is verified and created if not existing.
4.2 Different Server compile setups/ extensions
4.2.1 UDF support
Aside calling single Harbour command with leto_UDF( "cCommand"[, xParam] ),
you can load your own PRG-level functions with a <HRB> file also during the server is running.
A very basic example is found in: tests/letoudf.prg.
How to compile a PRG to a HRB, look into letoudf.hbp. This is called with: hbmk2 letoudf.
Place the resulting <HRB> file in same directory as the server executable.
After the "reload" command or together with server start you have an entry in letodbf.log if they
were successful loaded. In case of error you shell also find a short text what have failed.
See further at Leto_Udf() ...
For the execution of Harbour functions at server side, or when your functions in the HRB file
need Harbour commands ( like "STR", "DTOC" ), these Harbour functions must be linked during compile
into the server executable.
By default most common used are allready available, done by a REQUEST in source/server/server.prg.
If you need some special Harbour core function, you can add your own REQUEST in source,
or easy enable the full Harbour command set by activating ( remove '#' ) in letodb.hbp.
The full set of the Harbour Cl*pper tools contrib [CT] function can be get the same place.
* In server mode No_Save_WA=0: for all tables; and for all HbMemIO tables in any server mode: *
at server side the ALIAS name for a workarea is *different* to that used in your application.
Client ALIAS is *automatically* translated if part of <cCommand> string e.g. in codeblocks.
If you want to access at multiple workareas simultanous in your UDF, and such WA is not the active one,
UDFs functions in HRB are needed. Here then to work with Leto_Select() for above specified WA and
Leto_Alias() for all other tables to query for the WA ALIAS name at server.
The ALIAS at server for these tables is not predictable because dynmically created,
( FYI: scheme is: "Exxxxxxx", where x is a number of sequential occurance to create such an ALIAS global
to server for all connections -- it is re-used after a workarea is lastly closed. )
4.2.2 Codepage support
This topic relates mainly to index files.
Each connection can use a different codepage.
Each connection is actually limited to use same codepage for all its tables.
You should avoid to open the *same* DBF aka its index files with different codepages.
These limits i may extend, if possible, in future if its' really needed.
It is important, with which CP setting the index was created and then later DBF data is modified.
If your questions now are: what is a codepage ? -- how do i determine the used codepage in my sourcecode ?
-- what is the command to change in my sourcecode the codepage ? -- and similar questions ...
indicate, that you are using default settings. Then you are nearly done about this section.
In the file: source/include/letocdp.ch
you may adapt the list of available codepages. These can then be enabled/ loaded for a client connection.
! After changing content in that include file, you have to rebuild the server !
The names in that file are the same you use in your sourcecode, but with prefix: HB_CODEPAGE_MyCodepage
Above shell be the recommended way to adapt the list of possible codepages.
Alternatively, you can enable *all* by Harbour known codepages by outcommenting in:
letodb.hbp ( ledodbaddon/ letodbsvc ) the line with: "__HB_EXT_CDP__" [ remove the '#' at beginning ]
4.2.3 Rushmore bitmap index support
Before you believe, this will be the mother of filtering performance problems, let be told she isn't.
Better to invest a bit time about how to get optimized *server-side* filters with help of the Leto_Var*()
system, see section 5.2 and search for the Leto_VarGetCached() idea ...
Because to get the array with record numbers to be set as valid, it must be skipped one time through the
whole database, in opposite to first suggest where this is done for so many records as just needed.
To update this 'fixed set', again a full run is needed, where above suggest just actualizes the expression.
The server and the client library can be built with support of the driver BMDBFCDX/ BMDBFNTX/ BMDBFNSX.
In this case, these RDD will be used by default, aka e,g. BMDBFCDX if "CDX" is found in letodb.ini
Basically they support the same functionality as classic CDX/ NTX, but there are five functions to set
bitmap filters, see section 7.11
To build server for this, you need to uncomment in the hbp file / letodb.hbp, rddleto.hbp ) a macro:
"__BM", done with removing of the '#' at beginning of lines with that "__BM".
Then re-compile *both* sides sides of LetoDBf, aka server executable and client library.
As they are implemented as an UDF call, you must also set in letodb.ini Allow_UDF = 1.
4.2.4 Compression LZ4 / ZLib
Default is to use highspeed realtime LZ4 compression algorithm, but stoneage BCC 5.5 compiler cannot use it !
This can be changed to classic ( slower! ) ZLib compression by outcommenting with set a < # > into first position
of the corresponding .hbp files, found at very top the line with: "#-env:__LZ4=yes"
I would very recommend lightning fast LZ4.
Re-compile both!! server executable and client library. This must fit together, a server with LZ4 won't understand
a client application with ZLib.
Additional remark: at least stoneage old BCC 5.5 had problems with using LZ4, so it is outcommented for all BCC
versions. If you want to try it with a newer BCC version you have to remove that: "{!bcc}" in the HBP files.
4.2.5 special build options
A few special flags can be passed with hbmk2, the universal form is:
hbmk2 ... -cflag=-D...=...
hbmk2 ... -prgflag=-D...=...
This sets a: #define to the value, to be active for PRG- and/or C- sources. As it is not allowed to re-define
an already set value, this is possible only for a few #defines used in LetoDBf. Example:
hbmk2 letodb -cflag=-DLETO_SENDRECV_BUFFSIZE=32767
will be alike as in C-source: #define LETO_SENDRECV_BUFFSIZE 32768
# C-source flags:
LETO_SENDRECV_BUFFSIZE
change the default size of 64 KB for send/ receive/ encrypt buffers for the server executable.
Use following formula for different values: ( x * 8192 ) - 1
It can be used to spare a bit RAM usage of the server if needed, low values will lead to often reallocation,
and bigger than 64KB rarely increase the performance. With debug level > 20 you find hints about such activity.
It can be used also for the client library with e.g. hbmk2 rddleto, but as your application commonly have only
few connections it will have less influence on RAM usage.
LETO_USERPASS
Internal password for the user credentials database, see 4.3 Authentication
LETO_MYPASSWORD
Hardcoded password in the server executable *and* the client library: they must be the same for both sides !,
else a connection to the server will fail, see: 4.5 Security
# PRG-source flags:
LETO_FULLCMDSET_HB
LETO_FULLCMDSET_CT
These flags activate the full Harbour and/ or the full set of CT [ Cl*pper Tools ] contrib.
Use these only if really needed, and before doing so, please verify that a wanted function is not already
REQUESTed in 'source/server/server.prg' -- better to inform LetoDBf developer to add a missing important one,
and it also can be done by the end user itself.
4.3 Authentication
To turn authentication system on, aka to log into server with required username/ password,
you need to set one of the following letodb.ini parameters to 1:
Pass_for_Login, Pass_for_Manage, Pass_for_Data.
! Beforehand, you need to create at least one user with admin rights, because when authentication
system is active, only authenticated users with admin rights are able to add/ change users
and passwords.
To add a first user, you need to execute LETO_USERADD() one time, for example:
LETO_USERADD( "admin", "secret:", "YYY" )
where "secret" is the password, and "YYY" is a 3 letter Y_es and N_o string,
which grants rights to; 'admin' 'manage' 'write access'.
You can also use the console program in utils/manager/console.prg to add/ delete users.
To connect to a server with username and password when authentication is activated,
you must use the LETO_CONNECT() function.
Then also the console monitor needs to login with username/ password - see section 8.1 for params.
The user credentials are read during server start, its content is kept in memory,
aka deleting this file needs a server restart to reset ( plus revoking authentication required ).
Default place in server directory can be adapted with config option: 'Pass_file' with an [absolute] path.
User credentials are encrypted with a default password burned in the executable,
which can be personalized for your environment, e.g.:
hbmk2 letodb -cflag=-DLETO_USERPASS=AbsoluteSureNobodyKnowMe
A new executable with a different password makes the old user credentials invalid, needs to start from scatch.
4.4 Samba file service
If files served by a Samba server to its clients need to be shared with a LetoDBf server,
LetoDBf must be special configured.
Technical background: <exclusive> OS file-system flag for an opened file is not set, nor even
checked by Samba server -- handled only internally in Samba, its not visible to Linux server.
Moreover an <exclusive> open table done at a CIFS network-drive will appear ever as a <shared> one,
* so such <exclusive> table opened by LetoDBf can be opened shared by a Samba application *
LetoDBf server does its best to ensure data integrity, respects exclusive opened tables by Samba,
but need an additional check for <exclusive> tables opened by it.
Basis of at least a partially co-work is to mount the handled <share> at Linux server, from
where it is served, and where LetoDBf server(s) will run concurrently on same data.
( Commonly you need package: <cifs-utils> to be able to mount a CIFS network file system.
Create a mount-point [ /mnt/samba ], and mount the share there;
it can be done e.g. in /etc/fstab or with a mount command in startup init-script:
mount -t cifs -o guest,file_mode=0666,dir_mode=0777 //localhost/share_name /mnt/samba
the ',' separated options [-o] list reflects needs in your Samba server setup )
SINGLE server: you can use a single LetoDBf server as usually, and point in letodb.ini
DataPath = /mnt/samba, set: Share_Tables = 1 and add special option: SMB_SERVER = 1.
*Problem: performance of LetoDBf server working on a network drive, is *drastic* slower
as working on a real hard-drive.
DOUBLE server: then following strategy is used:
<exclusive> table are opened at the LetoDBf server working on the network drive
<shared> tables are opened at both! server, where all active work happen at hard-drive.
The opened table at network drive is to inform Samba user and prevent them to open it <exclusive>.
* This all will happen fully automatic for the LETO RDD client application, no need to care about *,
but the setup is much more complex:
# create a copy of letodb.ini ( letosmb.ini ) and adapt therein:
-- use different port, e.g.: Port = 2814
-- DataPath to point to CIFS mount-point [ e.g. /mnt/samba ] or a sub-directory of it
-- LogPath can be the same, but set: Debug = 0 to get only errors
-- add Entry: SMB_SERVER = 1
this will use 'smbstatus -L' check to ensure concurrency for <exclusive> table
-- For lowering delays, possible caused by the 'smbstatus -L' call, optional add also:
SMB_PATH = /absolute/path/of/share:/mnt/samba
Left side is the absolute path of the <share> at server, right side the <mount-point> from
above mount command or /etc/fstab entry -- with no blanks around the ':' delimiter.
*Build* the 'elsof' executable in 'tests/c_lang/elsof.c' --> see at top in that file how to.
Without this option, 'smbstatus' is used, and both executables are expected to be in
'/usr/bin'. In case of problems to execute, you get an error message in letodbf.log.
-- *both* .ini files need option: Share_Tables = 1
# start both server with option to specify an ,ini filename, literally in example:
letodb config letodb
letodb config letosmb
( shutdown is similar, e.g.: letodb stop letodb; letodb stop letosmb )
* RDD library adaption
# outcomment (remove the '#') for LETO_SMBSERVER = 1 in the hbmk2 make files:
rddleto[addon].hbp
Rebuild RDD library, to get a different behavior to work on two server
# in your application you need to connect to *both* server with Leto_Connect(),
Connect to the one with letosmb.ini *before* the common default connection,
[ to avoid an afterwards need to swich back ]
# in directory of your application is a 'rddleto.ini' config file needed:
copy tests/rddleto.txt as sample to the place, and set therein:
SMB_SERVER = IP|DNS-name
SMB_PORT = 2814
[ the port you choosed in letosmb.ini, and the address or name of your servers ]
SAMBA application adaption,
# build: hbmk2 tests/excltest.prg
and copy the executable e.g. into the root directory of the <share>.
# copy tests/rddleto.txt as excltest.ini into the same directory;
this will be specific to that exe as with same filename
# adapt in excltest.ini:
SMB_SERVER = its.IP.address ( to spare DNS resolution time for each call )
SMB_PORT = 2814 ( for single server setup default port is 2812 )
This executable must be called after any successful <shared> opened table.
It set OS ErrorLevel as result to 1, if table is already <exclusive> used,
then the just <shared> open was invalid and table must be immediate closed.
See at top in tests/excltest.prg for further instructions how to use.
4.5 Security
By default LetoDBf listen to all interfaces with empty config option: IP
If the server have also an interface connected to the internet, it is recommended to
limit this to the interface ( given by IP-address or Unix device name ) with the intranet.
Doing so will also exclude the local loopback (lo) device.
If not wanted, if there is only one interface for internet and intranet, or having multiple
interfaces for the intranet for load balancing, leave the IP option empty and set instead
option: IP_SPACE to limit the allowed IP address-spaces.
This string contains lefthand parts of the allowed IP-address range, delimited with ';'.
For establishing a new connection to the server, a hardcoded password is used.
'Hardcoded' means it is burned into the server executable and in the client library.
These passwords must be the same for server and RDD library, else connecting will fail.
By using another string for 'LETO_PASSWORD' in 'include/funcleto.h', you can personalize
your server only to be connected by applications linked with your client library.
To change value of LETO_PASSWORD *without* source code change, use switch to set flag:
hbmk2 [letodb|rddleto] -cflag=-DLETO_MYPASSWORD=MyOwnSecurePassword
where <MyOwnSecurePassword> can not contain ',' and avoid single and double quotation marks.
[ getting a compile error indicates the password string is invalid ]
As these passwords are burned into as 'plain text', it is fine they consist of no real words,
have a look for the default.
LetoDbf server can be configured to forcible accept only connections with username/ password.
See herefore: 4.3 Authentication
Further LetoDBf offers blowfish encrypted network traffic in CBC mode.
This is activated on demand in conjunction with network compression, by using the cPassword>
parameter in Leto_Togglezip( nLevel, cPassword ).
Compression ( plus encryption ) can be activated immediate after a connection is established.
NEW: with server option "CRYPT_TRAFFIC" network traffic encryption is demanded to be used by
client, this is like above Leto_Togglezip() from the very beginning using a random password.
It will block any connection which is not using encryption.
5. How to work with the LetoDBf server
5.1 Connecting to the server
# .. without source change -- NEW [ not xHarbour ]
By providing a "rddleto.ini" ( sample file "rddleto.txt" in "tests" dir ) with server IP|DNS name,
[ Server = ... plain name or with preleading "//" and optional server port ':' ],
--> your application at startup, during the init of "LETO" RDD, tries to connect to the server,
and !quits! if that failed.
Use 'DETECT' instead server IP|DNS to broadcast for server with a Leto_Detect() at app start,
which have set in letodb.ini [ BC_Service ] to answer such requests.
That means no config work to be done, the server must be up and clients should then find it.
# .. with adding a few lines source
The 'traditional' common way is to add a short sequence about "leto_Connect()" to existing source,
example place it in function main(). Take a look into 'tests/basic.prg'
IF leto_Connect( "//192.168.7.42:2812/" ) < 0
Alert( "Can't connect to server ..." )
QUIT
ENDIF
This opens possibilities like multiple connect requests, detailed feedback about failed,
or if you application need to connect to multiple ! LetoDBf server, check detailed params of
leto_Connect() in: 7.1
If you need to make source changes specific for LetoDBf, to keep your source portable for usage
without LetoDBf you may like to encapsulte them alike:
#ifdef RDDLETO_CH_
... special for Leto
#endif
5.1.2 building your application
Hopefully you did not set the second param of: DbUseArea( , cDriver, ... )
or used the "VIA" option of the "USE command": then remove cDriver for all WA to be used with LetoDBf.
This will make your application portable to also other RDD as LETO, as the default RDD can be easy
determined at program start by setting: RDDSetDefault( "XXXX" ), e.g. "DBFCDX".
A successful login to the server sets the default RDD to "LETO".
Most easy and highly recommended is to build your app for LetoDBf by using "letodb.hbc" for hbmk2.
You can include it into your project HBP by adding it in an extra line, or use it at command line:
hbmk2 yourapp[.prg|.hbp] letodb.hbc
It automatize for you the following steps:
a) add LetoDbf library and include paths for the linking process
b) request to link the LetoDBf RDD driver, else it must be set manually outside the main() procedure
REQUEST LETO
c) includes the header file: "rddleto.ch", else it must be done manually in every of your PRG:
#include "rddleto.ch"
or
it can be done by using the <-u+> option for Harbour: -u+rddleto.ch
d) same as for c) includes the header file: "leto_std.ch"
e) set the switch "-mt=yes" to link your application with LetoDBf client library with multi-thread support.
Further an internal, additive idletask is activated, if your application is build with '-mt'.
and at end links the "rddleto" client lib functions called in your source into the executable.
5.1.3 successful connected to server
This will set the default RDD driver to "LETO" after connecting similar done with: RddSetDefault( "LETO" ).
Also the server is informed about four SET settings: DELETED/ SOFTSEEK/ AUTOPEN/ AUTORDER.
With connection to the server, and later with opening or creating a table, information about codepage
and dateformat settings are sent to server. This is important for creating index orders containing
national special characters or index keys containing a date value.
The last applied dateformat setting will be from then on the active one at server.
All filenames and paths are now relative to the root DataPath in letodb.ini.
It may look alike: ( to this example i refer in the following explanations )
DataPath = [drive:]\path\to\data_diretory
If none DataPath is given ( ! NOT ! recommended ), it will be the root directory with the server
executable.
Example: DbUseArea( .T.,, "test\customer.dbf" ) will open DBF in:
[drive:]\path\to\data_diretory\test\customer.dbf.
A drive letter in your filenames will be cut away, and only one "..\" directory step up higher than
the <DataPath> in letodb.ini is allowed. This means: DbUseArea( .T.,, "..\data_other\customer.dbf" )
will point to:
[drive:]\path\to\data_other\customer.dbf.
If your filenames contain at least one path seperator '/' or '\', they will be treated as relative to
<DataPath>. All path separators in your filenames are converted by LetoDBf server internal to the needed
one, no need to take care about as "\" or "/" is equal.
This root path is equal a SET DEFAULT TO setting, so if your filenames contain *no path separator,
all new files will be created directly in <DataPath>.
The filenames can have optional OS dependent leading '\' or '/', example: /mydbf.dbf, that will force
them into the <DatPath> directory, despite a given "SET DEFAULT" to a subdirectory.
For blank, pure filename the "SET DEFAULT TO ... " setting, when set *before* Leto_Connect() will name
an additive sub-directory to <DataPath>. Example: "SET DEFAULT TO data" will put all NEW files without
path separator into:
[drive:]\path\to\data_diretory\data
!! Allowed for "DEFAULT" is only one single path, NOT ENDING WITH ';' OR ":" !!
The example setting of "SET PATH TO system;tmp" will lead to search for files in:
[drive:]\path\to\data_diretory\system and [drive:]\path\to\data_diretory\tmp
If you use: DbUseArea( ,, cFile, .. ) and it is not in the DEFAULT directory, but in one directory given
by SET PATH, it will be opened without further needed action from you.
Both DEFAULT and PATH recognize the <DataPath>, what means a "SET DEFAULT TO to\data_diretory\data" will
lead to a DEFAULT directory: '[drive:]\path\to\data_diretory\data' as given as "SET DEFAULT TO data".
!! Again, both settings of "DEFAULT" and "PATH" apply to filenames without any path seperator '\' or '/'.
To check for some first examples, look into the "tests" directory. Build them all at once with: "buildall"
resp. "-/buildall.sh" for Linux. Add for execution as first param the IP address of the server,
if unknown but at same machine running as the application use loopback network: 127.0.0.1
At any case you shell try the "test_file" executable, as about a not working "Leto_File() functions exist
multiple! miles long mysthic threads at Harbour Google group about its inner magic :-) 8-) !!
The other, not recommended way because of not being portable, is to open a DBF table with the
'on the fly' method by adding IP-address[:port] plus relative path to Harbours 'USE' command,
example:
USE "//192.168.5.22:2812/mydir/test"
will open file in:
[drive:]\path\to\data_diretory\mydir\test.dbf.
After doing this an initial time, you are also connected to the server and would need for the next calls
no more IPaddress:port prefix more. This is a hint for experienced LetoDB users to think about.
5.2 Filters and Relations
5.2.1 Filters
The filter is established usually: by the SET FILTER TO command or by calling DbSetFilter() function.
Most important param of DbSetFilter() is the expression, the second param: DbSetFilter( bBlock, cExpression )
as only this can be transmitted to the server. ( codeblocks are not exchangeable between applications )
The filter expression which can be executed at the server is called "optimized".
If the filter must be executed locally at client, it is called: "not optimized". Such filter is slow as all
records must be received from the server, and the client have to discard all the invalid records.
In case of an optimized filter, only valid records are send to the client application.
To get an optimized filter, it is necessary, that the expression is solely executable for the server.
So all the functions therein, like standard Str(), Upper(), DToS() etc must be known to the server.
If your expression contains an own function from yourself, this can be loaded with a HRB file any time during
a running server, see therefore 4.2.1 UDF supprt.
If your expression contains a variable only known to you application, the mighty Leto_Var*() system comes into
action. With this you can share the content of a variable at client side with the server, and vice versa.
So with the help of leto_Var*() functions plus UDF loadable functions plus a rich set of classic Harbour
commands, it is possible to turn any non-optimized filter into an optimized.
These are lightning fast and a pleasure to work with. To test, whether a filter is an optimized, just check
for with the LETO_ISFLTOPTIM() function, if it returns TRUE.
Following two settings influence the use of optimized, server side filters:
SET( _SET_OPTIMIZE, .F. ) will disable any filter evalution at server, so every filter will become a
non-optimized filter to be executed by client [ the default is .T. == allow them ].
Only in server mode: No_save_WA = 1 and then setting:
SET( _SET_FORCEOPT, .T. ) will enable filter expressions at server with ALIAS names, maybe of an relationed
workarea. [ default is .F. == ALIAS not allowed ].
Server mode No_Save_WA = 1 is needed with ALIAS names other than the active WA, because in mode '0' LetoDBf
server uses WA detaching/ requesting technics and other WA are not available/ detached, and so there is no
relation active at server.
With ForceOpt = TRUE a filter expression MUST be valid at server, else a RTE is thrown -- it will NOT be
evaluated alernatively at client as without ForceOptimize.
[NEW] If the filter expression contains a PRIVATE/ PUBLIC memvar, they will be synced between client and server
with help of the LetoVar() system. A unique Leto_VarCreate() with value of the memvar is executed, the filter
string expression is automatically modified to use a Leto_VarGet() instead of the memvar.
With each move ( GoTo[p|bottom], Skip, Seek ) in the WA, a possible changed memvar value is automatic synced
with a new Leto_VarSet() call. Clearing the filter, also done with closing the table, will Leto_VarDel() all
created LetoVars.
Example: 'SET FILTER TO table->field > xMemvar' will work as without LeotDBf, but as optimized filter.
See also Leto_VarExpr*() functions if you want to do it manually, or for other occasions.
Performance optimization for can be done by adapting default settings for size/ timeout of the skip-buffer:
See chapter 7.3 for DBI_BUFREFRESHTIME, DBI_AUTOREFRESH and 7.5 for LETO_SETSKIPBUFFER()
5.2.2 Relations
In server mode: No_Save_WA = 1 relations are additional active at server side. This is not possible for server
mode: No_Save_WA = 0, here the relations are only active at client side.
To transmit the relation expression to the server, the second param of DbSetRelation( bBlock, cExpression ) is
needed, as only a string can be transfered to the server, no codeblock.
By using the command: "SET RELATION TO ... INTO ..." this second param is filled automatically through the
header file: <std.ch>, which is anytime included for any Harbour application. This second param have to be set
manually if the function DbSetFilter() is used. Be careful that bBlock and cExpression mean the same.
If cExpression contains an error, or is not executable at server side because of a function known only in
your application ( see 4.2.1 UDF support ) or client application variables ( see 7.9 Server variables ), you will
get a RTE with a description what failed at server.
Setting a 'cyclic relation', aka a set of relations where one relationed child area refer back to an parent area,
lead to an RTE informing you about. The most simple 'cyclic relation' is a relation pointing to itself workarea.
5.3 Database driver
If nowhere explicitely set, the default database driver for the server is DBFCDX.
This default driver at server can be changed in the letodb.ini with setting of Default_Driver.
The active driver for your connection you can query and !SET! with:
leto_DbDriver( [ <cNewDriver> ], [ <cMemoType> ], [ <nBlocksize> ] )
==> aInfo