File: manual.html

package info (click to toggle)
msql 2.0.3-5
  • links: PTS
  • area: non-free
  • in suites: hamm, slink
  • size: 3,596 kB
  • ctags: 2,483
  • sloc: ansic: 34,769; sh: 1,309; yacc: 1,084; perl: 328; makefile: 267
file content (5716 lines) | stat: -rw-r--r-- 284,126 bytes parent folder | download
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>mSQL 2.0 User Guide</TITLE>
</HEAD>
<BODY TEXT="#000000" LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">

<FONT SIZE=2><B>Please Note</B> : This HTML version of the mSQL 2.0 documentation is a rough
approximation of the documentation.  Some of the formatting of the original Postscript
version of this document are lost during the translation to HTML.  Please see the Postscript
version of this manual, available with the mSQL 2.0 distribution, for a correct representation
of the documentation.  This file is provided as a convenience for on-line viewing, not as
a replacement for the actual user guide.
</FONT>
<HR>

<B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><IMG SRC="deer.gif" WIDTH=530 HEIGHT=105></P>
</FONT><B><FONT SIZE=7><P ALIGN="JUSTIFY">&nbsp;</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT SIZE=7><P ALIGN="CENTER">Mini SQL 2.0</P>
</B><P ALIGN="CENTER">User Guide</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">Release Version&#9;&#9;mSQL 2.0.1</P>
<P ALIGN="JUSTIFY">Release Date&#9;&#9;23 July 1997</P>
<P ALIGN="JUSTIFY">Document Revision&#9;&#9;2.0.1 v 1</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>

<P ALIGN="CENTER">Copyright &copy; 1997 Hughes Technologies Pty Ltd.  All rights reserved.</P></DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=4><P ALIGN="JUSTIFY">Intended Audience</P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">This document has been prepared as a manual for the use of the Mini SQL database system.  It is not a general purpose tutorial or text for learning every aspect of the Structured Query Languages (SQL).  The reader is expected to have at least an introductory knowledge of SQL and the concepts of a relational database system.</P>
<P ALIGN="JUSTIFY">The mSQL API section of this document covers the programming interface provided by mSQL.  It is described in the native language of the API library, C.  It is assumed that the reader has a good understanding of programming in the C language and that s/he is familiar with the basic functionality provided by the standard C library.</P>
<P ALIGN="JUSTIFY">The Lite section of the manual documents the Lite programming language.  The syntax and semantics of the Lite language are similar to those of the C language.  A working knowledge of C will aid the reader in understanding the Lite language.</P>
<P ALIGN="JUSTIFY">Integration of mSQL and the World Wide Web is covered in the W3-mSQL section.  It is assumed that the reader is familiar with the WWW, HTML, CGI scripts and the operation of a web server (http daemon).</P>
</FONT><B><FONT FACE="Helvetica" SIZE=4><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Document Conventions</P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">This manual has been designed to be printed on US Letter paper.  While many parts of the world utilise the A4 paper size (Australia included), it is not possible to print A4 formatted documents on US Letter paper without loss of information.  However, printing of US Letter formatted documents on A4 will result in a correct representation of the document with somewhat larger margins than normal.</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Throughout this manual, parts of the text have been flagged with the symbol that appears in the margin opposite this paragraph.  Such pieces of text are viewed as being important.  The reader should ensure that paragraphs marked as important are read even if the entire manual section is only being skimmed.  Important sections will include information such as areas in which mSQL may deviate from other SQL implementations, or tips on improving the performance of your database applications.</P>
</FONT><B><FONT FACE="Helvetica" SIZE=4><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Contact Information</P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Further information about mSQL and its related software can be found on the Hughes Technologies World Wide Web site.  The web site includes the latest version of mSQL, documentation, example software, references to customer sites, and much more.  Our web site can be found at</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>http://www.Hughes.com.au</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Product support and information are available over the Internet via electronic mail.  For product support, please contact </FONT><FONT FACE="Helvetica-Narrow" SIZE=1>support@Hughes.com.au</FONT><FONT SIZE=2> and for product information please use </FONT><FONT FACE="Helvetica-Narrow" SIZE=1>info@Hughes.com.au</FONT><FONT SIZE=2>.  More traditional ways to contact us are via postal mail or facsimile using the information below.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=655>
<TR><TD WIDTH="19%" VALIGN="TOP">
<B><FONT SIZE=2><P ALIGN="JUSTIFY">Postal Mail</B></FONT></TD>
<TD WIDTH="81%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">PO Box 432</P>
<P ALIGN="JUSTIFY">Main Beach</P>
<P ALIGN="JUSTIFY">Queensland  4217</P>
<P ALIGN="JUSTIFY">Australia</FONT></TD>
</TR>
<TR><TD WIDTH="19%" VALIGN="TOP">
<B><FONT SIZE=2><P ALIGN="JUSTIFY">Facsimile</B></FONT></TD>
<TD WIDTH="81%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">+61 7 5529 2299</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT>

<B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767716">Introduction</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Mini SQL, or mSQL as is it often called, is a light weight relational database management system.  It has been designed to provide rapid access to data sets with as little system overhead as possible.  The system itself is comprised of a database server and various tools that allow a user or a client application to communicate with the server.</P>
<P ALIGN="JUSTIFY">Although mSQL uses the Structured Query Language (SQL) as its query language, it does not provide a complete implementation of the ANSI standard SQL.  Several features of SQL that are found in more recent versions of the ANSI standard and in more sophisticated database systems are not provided by mSQL.  The incorporation of such features would be in conflict with the basic concept of mSQL (i.e. a Mini database system) and would also increase the load and system requirements needed to run the software.</P>
<P ALIGN="JUSTIFY">The philosophy of mSQL has been to provide a database management system capable of rapidly handling simple tasks.  It has not been developed for use in critical financial environments (banking applications for example).  The software is capable of performing the supported operations with exceptional speed whilst utilising very few system resources.  Some database systems require high-end hardware platforms and vast quantities of memory before they can provide rapid access to stored data.  mSQL has been designed to provide exceptional data access performance on &quot;small hardware&quot; platforms (such as PC class hardware).  Because of these characteristics, mSQL is well suited to the vast majority of data management tasks.</P>
<P ALIGN="JUSTIFY">Although the mSQL software distribution is made available over the Internet (and other mechanisms) it is not public domain software or FreeWare.  mSQL is a commercial, supported software package developed by Hughes Technologies Pty Ltd in Australia.  Use of this software in any commercial environment requires the purchase of a commercial use license from Hughes Technologies.  Free licenses are provided to organisations such as Universities, schools and registered charities in an attempt to maintain the ethos of the original Internet.  For more information on purchasing a license or determining whether you qualify for a free license, please see the Hughes Technologies World Wide Web site at </FONT><A HREF="http://Hughes.com.au/"><FONT SIZE=2>http://Hughes.com.au/</FONT></A><FONT SIZE=2>.</P>
<P ALIGN="JUSTIFY">Development of mSQL and its associated tools is an ongoing project.  Current releases of the mSQL package and applications that use mSQL are always available from the Hughes Technologies web site.  If you require product support, a new version of the software, or some ideas about using mSQL then please visit our web site.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767717">Mini SQL 2.0</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Mini SQL 2.0 is the second generation of the mSQL database system.  The main focus of the second generation development has been to extend the capabilities of the database engine and to provide new tools to simplify the development and delivery of mSQL based applications. The large acceptance of mSQL 1.x highlighted several shortcomings of the original product because it was being applied to applications beyond its original design intention.  Applications managing databases with up to a million records were being reported and, naturally, the performance of the 1.x engine was not appropriate for the task.</P>
<P ALIGN="JUSTIFY">The database engine in mSQL 2.0 has been designed to handle large data sets and to provide consistent and rapid access to large data sets in the million record size.  In doing so it has in no way compromised the outstanding performance shown by the 1.x engine in handling small data sets.  The performance increase for large applications has been achieved by the incorporation of flexible and powerful indexing to the database as well as sophisticated query execution optimisation.  To learn more about the new indexing capabilities provided by mSQL 2.0, please see the </FONT><I><FONT FACE="Helvetica" SIZE=2>mSQL Query Language</I></FONT><FONT SIZE=2> section of this manual.</P>
<P ALIGN="JUSTIFY">One of the major applications of mSQL has been as a back-end database for World-Wide Web sites.  With this fact in mind, mSQL 2.0 includes the new W3-mSQL www interface package.  Using W3-mSQL, web based applications can be rapidly developed by embedding mSQL and other programmatic constructs directly into the HTML code.  This removes the need to write a multitude of small CGI scripts for every web page with dynamic content.</P>
<P ALIGN="JUSTIFY">Also included in the 2.0 distribution is the Lite scripting language.  Lite is a stand-alone version of the language used by W3-mSQL.  By including Lite in the distribution, a developer has a consistent language that s/he can use to develop stand-alone or web based applications that utilise mSQL.  Further information about Lite and W3-mSQL is provided in the following sections of this manual.  Further information on the new features in mSQL 2.0 can be found in Appendix A.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767718">Installing mSQL 2.0</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">For the eager reader, an overview of the compilation and installation process can be found below in the </FONT><I><FONT FACE="Helvetica" SIZE=2>Express Setup</I></FONT><FONT SIZE=2> section</P>
<P ALIGN="JUSTIFY">Mini SQL is generally distributed in source code form to enable the widest possible use of the software.  It is not feasible for binary distributions to be generated for every UNIX platform for each release of mSQL.  Instead, the software and the installation tools have been made as portable as possible.  In general, the software will automatically configure itself to the capabilities of the operating system on which it is being compiled.  Typing four commands can complete the process of compiling and installing mSQL on most UNIX platforms.  Only under extreme situations will the software not compile &quot;out of the box&quot;.  Hints for getting the software compiled on troublesome operating systems is available in the </FONT><I><FONT FACE="Helvetica" SIZE=2>Installation Troubleshooting</I></FONT><FONT SIZE=2> section below.</P>
<P ALIGN="JUSTIFY">The software is distributed as a gziped (i.e. compressed) tar file.  Tar is a standard UNIX facility for combining many files and directories into a single archive file.  The tar utility should be available on any modern UNIX system.  If your system does not provide the tar utility then a freely available version of tar has been produced by the Free Software Foundation (the GNU project).  The GNU version of tar can be found on any GNU archive site.  Similarly, the gzip compression tools are produced by the Free Software Foundation.  If your system does not provide the gzip or gunzip utility then you will need to obtain these from your nearest GNU archive site.</P>
<P ALIGN="JUSTIFY">The table below shows a selection of commonly used GNU archive sites.  To access these site use anonymous FTP (or the URL provided).  A complete list of GNU software mirror sites can be found at http://www.gnu.org/order/ftp.html.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="22%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Country</B></FONT></TD>
<TD WIDTH="25%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Hostname</B></FONT></TD>
<TD WIDTH="18%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Directory</B></FONT></TD>
<TD WIDTH="35%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">URL</B></FONT></TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Australia</FONT></TD>
<TD WIDTH="25%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">archie.au</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">/gnu</FONT></TD>
<TD WIDTH="35%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp://archie.au/gnu</FONT></TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">U.S.A</FONT></TD>
<TD WIDTH="25%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">prep.mit.edu</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">/pub/gnu</FONT></TD>
<TD WIDTH="35%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp://prep.mit.edu/pub/gnu</FONT></TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">U.S.A</FONT></TD>
<TD WIDTH="25%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp.uu.net</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">/systems/gnu</FONT></TD>
<TD WIDTH="35%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp://ftp.uu.net/systems/gnu</FONT></TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">U.S.A</FONT></TD>
<TD WIDTH="25%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">gatekeeper.dec.com</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">/pub/GNU</FONT></TD>
<TD WIDTH="35%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp://gatekeeper.dec.com/pub/GNU</FONT></TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">United Kingdom</FONT></TD>
<TD WIDTH="25%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp.mcc.ac.uk</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">/pub/gnu</FONT></TD>
<TD WIDTH="35%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ftp://ftp.mcc.ac.uk/pub/gnu</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=1><P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767719">Getting Ready to Compile</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Before the software can be compiled, the contents of the archive file must be extracted.  This involves uncompressing the archive file with gunzip and then using  the tar utility to extract the file.  If, for example, the file containing the mSQL distribution is called msql-2.0-rel.tar.gz then the following commands would extract the files (two methods are outlined)</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>gunzip msql-2.0-rel.tar.gz</P>
<P>tar xvf msq-2.0-rel.tar</P>
<P>&nbsp;</P>
<P>Or</P>
<P>gzcat msql-2.0-rel.tar.gz | tar xvf -</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">This process would create a new directory called msql-2.0-rel in the current directory.  Within that directory you will find the entire mSQL distribution.  Along with various other files and directories there will be directories containing the source code (src directory) and the documentation (the doc directory).  Although it is tempting to just enter the src directory and type &quot;make&quot; it is not the correct way to compile mSQL and doing so will cause problems.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">The mSQL distribution is structured to allow it to be compiled on multiple machines using the same copy of the source code (source tree).  For example, the source tree can be shared between various machines using NFS and versions for each machine type can be compiled in the same source tree.  To achieve this, mSQL uses target directories for each machine type (hardware platform and operating system combination).  To create a target directory for your machine simply type the following from the top directory of the distribution</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>make target</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">This process will create a new directory called targets in the top directory.  In the targets directory you will find a target directory for your machine (for example targets/SunOS-4.1.4-Sparc or targets/FreeBSD-2.2.2-i386).  It is in this newly created target directory that you will compile the mSQL applications.</P>
<P ALIGN="JUSTIFY">To continue the compilation process, change directory to your target directory using cd targets/SunOS-4.1.4-Sparc for example.  Once you are in the target directory you can configure the compilation process.  The configuration process is totally automatic and will determine what system calls, library functions, and header files your operating system provides.  To configure the compilation process simply type</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>./setup</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">While the setup utility is executing you will see various pieces of information about your operating system being displayed as it is determined.  This output is informative only.  The results are automatically placed in files used by mSQL.  </P>
<P ALIGN="JUSTIFY">Once the automatic configuration is complete you may either compile the software using the default configuration settings or change the configuration settings from their default value.  There are two configuration items located in the site.mm file in the targets directory that you may consider modifying.  The configuration utility will try to determine the best C compiler to use on your system.  If you have multiple C compilers (a system compiler and gcc for example) you may wish to modify the CC entry in site.mm.</P>
<P ALIGN="JUSTIFY">The only other option in site.mm that may require modification is the INST_DIR entry.  This entry defines the default installation directory.  This setting is not only used during installation of the software but also as the directory containing the run-time configuration file.  If you intend running mSQL from a directory other than the default /usr/local/Hughes directory then modify the INST_DIR entry in site.mm to reflect your installation directory.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767720">Compilation and Installation</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Once the setup utility has completed you may compile the software by typing</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>make all</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The compilation process will traverse all the directories of the mSQL distribution and compile the C source code in those directories.  Status information is displayed to you as the compilation process proceeds.  If the compilation process stops with an error at any stage then please see the Installation Troubleshooting section below.  If the compilation has completed properly you will see a message on your screen informing you that you are ready to install mSQL.  </P>
<P ALIGN="JUSTIFY">Installation of mSQL can also be achieved using a single command, although you may need to have special permissions on your UNIX system (usually root access).  By default, mSQL will be installed in a directory called /usr/local/Hughes on your system.  If /usr/local is root owned on your system (as it is on most systems) then you will either need root access or you will have to get your system administrator to complete the installation for you.  If you are using a non-default installation directory then ensure that you have the required permissions to create the directory you specified.  To complete the installation simply type</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>make install</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767721">Configuring mSQL 2.0</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">mSQL 1.x offered several configuration options, including such details as the user the server should run as, the location of the TCP and UNIX sockets for client/server communications, the location of the database files etc. The problem with configuring mSQL 1.x was that all these details were hard-coded into the software at compile time. Once the software was compiled and installed you couldn't easily change those settings. </P>
<P ALIGN="JUSTIFY">To overcome this problem, mSQL 2.0 utilises an external run-time configuration file for definition of all these values. The file is called msql.conf and is located in the installation directory (usually /usr/local/Hughes). An application can choose to use a different configuration file by calling the new msqlLoadConfigFile( ) API function. All standard mSQL applications and utilities provide a command line flag, -f ConfFile , that allows you to specify a non-standard configuration file. When an application first calls the mSQL API library, a check is made to see if a configuration file has been loaded via a call to the msqlLoadConfigFile( ) function. If no such call has been made, the API library loads the default config file. Any values that are specified in that file will over-ride the normal operating parameters used by mSQL.   If no configuration file is found (or certain items are not set) then the default values listed below will be used.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767722">Structure of the config file</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The configuration file is a plain text file organised into sections. The file can contain blank lines and comments. A comment is a line that begins with the '#' character. Each section of the configuration file has a section header, which is written as the section name enclosed in square brackets (for example [ general ]). </P>
<P ALIGN="JUSTIFY">Configuration values within a section are presented using the config parameter name followed by an equals sign and then the new value. There can only be one entry per line and if an entry is defined multiple times in the one config file the last value defined will be used. If a parameter is not defined in the config file then an internal default value will be used at run-time. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767723">Elements of the General section</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The following configuration parameters are available in the general section of the config file. Please note that %I may be used in configuration entries to signify the mSQL installation directory (e.g. /usr/local/Hughes). </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=582>
<TR><TD WIDTH="14%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Parameter</B></FONT></TD>
<TD WIDTH="20%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Default Value</B></FONT></TD>
<TD WIDTH="66%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Definition</B></FONT></TD>
</TR>
<TR><TD WIDTH="14%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Inst_Dir</FONT></TD>
<TD WIDTH="20%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">/usr/local/Hughes</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The full path to the installation directory. This is the directory in which all the mSQL files are located (such as the program files, the database files etc). </FONT></TD>
</TR>
<TR><TD WIDTH="14%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">mSQL_User</FONT></TD>
<TD WIDTH="20%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">msql</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The user that the mSQL server should run as. If a user other than this user starts the server (e.g. it is started as root from a boot script) it will attempt to change UID so that it runs as the specified user. </FONT></TD>
</TR>
<TR><TD WIDTH="14%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Admin_User</FONT></TD>
<TD WIDTH="20%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">root</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The user that is allowed to perform privileged operations such as server shutdown, creation of databases etc. </FONT></TD>
</TR>
<TR><TD WIDTH="14%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Pid_File</FONT></TD>
<TD WIDTH="20%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">%I/msql2.pid</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The full path of a file in which the PID of the running mSQL server process will be stored. </FONT></TD>
</TR>
<TR><TD WIDTH="14%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">TCP_Port</FONT></TD>
<TD WIDTH="20%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">1114</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The TCP port number on which the mSQL server will accept client/server connections over a TCP/IP network. If this value is modified it must be modified on the machine running the client software also. </FONT></TD>
</TR>
<TR><TD WIDTH="14%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">UNIX_Port</FONT></TD>
<TD WIDTH="20%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">%I/msql2.sock</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The full path name of the UNIX domain socket created by the mSQL server for connections from client applications running on the same machine. </FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767724">Elements of the W3-mSQL section</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The following configuration parameters are available in the W3-mSQL section of the config file. These items impact on the operation of the W3-mSQL web interface package. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="18%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Parameter</B></FONT></TD>
<TD WIDTH="17%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Default Value</B></FONT></TD>
<TD WIDTH="66%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Definition</B></FONT></TD>
</TR>
<TR><TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Auth_Host</FONT></TD>
<TD WIDTH="17%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">NULL</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The machine on which the mSQL database containing W3-Auth data is located.  See the W3-Auth section for further details. If set to NULL (the default value) the database is assumed to be on the local host.</FONT></TD>
</TR>
<TR><TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Hughes_Footer</FONT></TD>
<TD WIDTH="17%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">True</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Controls the appending of the standard Hughes Technologies footer to Web Pages.</FONT></TD>
</TR>
<TR><TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Private_Only</FONT></TD>
<TD WIDTH="17%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">False</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">If set to True, the W3-mSQL interface will only process private pages (see the W3-mSQL section for information on private pages).  This may be used to enforce strict security on your system stopping remote users accessing normal HTML pages via the W3-mSQL cgi program.</FONT></TD>
</TR>
</TABLE>
</P>

<FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767725">Elements of the System section</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The following configuration parameters are available in the System section of the configuration file and determine the values of various system level configuration items.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="18%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Parameter</B></FONT></TD>
<TD WIDTH="17%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Default Value</B></FONT></TD>
<TD WIDTH="66%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Definition</B></FONT></TD>
</TR>
<TR><TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Msynch_Timer</FONT></TD>
<TD WIDTH="17%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">30</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Defines the interval in seconds at which the memory mapped data regions maintained in the mSQL server process will be synched with the on-disk images.  Setting this value to 0 will disable forced synchronisation of the data and rely on the kernels synching of the mmap regions.</FONT></TD>
</TR>
<TR><TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Host_Lookup</FONT></TD>
<TD WIDTH="17%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">True</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Determines whether ip address to hostname lookups are required.  If set to true, connections by hosts that do not resolve to a hostname will be rejected.</FONT></TD>
</TR>
<TR><TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Read_Only</FONT></TD>
<TD WIDTH="17%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">False</FONT></TD>
<TD WIDTH="66%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Forces the server to operate in read-only mode.  Any attempts to modify the database will be rejected (.e. the only commands accepted are <I>select</I> queries).  </P>
<P ALIGN="JUSTIFY">This option can be used if multiple database servers are to be run using the same data files.  In such a case only one server should be running in read-write mode with all others running in read-only mode.  This can easily be achieved by using different configuration files (specifying different TCP and UNIX ports as well) and loading the appropriate config file in the client application.</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY"><A NAME="_Toc393767726">Example configuration file</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Below is a sample configuration file. This file just sets the parameters to their default values. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>#</P>
<P># msql.conf  -  Configuration file for Mini SQL Version 2.0</P>
<P>#</P>
<P># This configuration sets all options to their default values. </P>
<P># Note : %I is expanded to the value of the Inst_Dir element is included in a value.</P>
<P>#</P>
<P>&nbsp;</P>
<P>[general]</P>
<P>Inst_Dir = /usr/local/Hughes</P>
<P>mSQL_User = msql</P>
<P>Admin_User = root</P>
<P>Pid_File = %I/msql2.pid</P>
<P>TCP_Port = 1114</P>
<P>UNIX_Port = %I/msql2.sock</P>
<P>&nbsp;</P>
<P>[w3-msql]</P>
<P>Auth_Host = NULL</P>
<P>Hughes_Footer = True</P>
<P>Private_Only = False</P>
<P>&nbsp;</P>
<P>[system]</P>
<P>Msynch_Timer = 30</P>
<P>Host_Lookup = True</P>
<P>Read_Only = False</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767727">Express Setup</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Below is a rough outline of the process of compiling, installing and configuring mSQL.  It is intended as a guide for those who are familiar with installing software on a UNIX machine.  If you are not familiar with any of the steps mentioned below then please read the complete installation guide from the start of this manual section.</P>
</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 1</B></FONT><FONT SIZE=2>&#9;&#9;Unpack the software distribution using gunzip and tar</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>gunzip msql-2.0-rel.tar.gz</P>
<P>tar xvf  msql-2.0-rel.tar</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P>
</FONT><B><I><FONT FACE="Helvetica-Narrow" SIZE=1><P>Or</P>
</B></I><P>gzcat msql-2.0-rel.tar.gz | tar xvf </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 2</B></FONT><FONT SIZE=2>&#9;&#9;Create a target directory for your hardware platform</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>cd msql-2.0-rel</P>
<P>make target</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 3</B></FONT><FONT SIZE=2>&#9;&#9;Configure the compilation process</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>cd targets/YourTargetDirectory</P>
<P>./setup</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 4</B></FONT><FONT SIZE=2>&#9;&#9;Check the default values of INST_DIR and CC in the site.mm file</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 5</B></FONT><FONT SIZE=2>&#9;&#9;Compile the software</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>make all</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 6</B></FONT><FONT SIZE=2>&#9;&#9;Install the software</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>make install</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT SIZE=3><P ALIGN="JUSTIFY">Step 7</B></FONT><FONT SIZE=2>&#9;&#9;Configure the software by editing the msql.conf file in the installation directory</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767728">Installation Troubleshooting</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Outlined below are some common problems encountered while installing mSQL.  If you continue to have problems compiling or installing mSQL after you have checked the following sections, please e-mail support@Hughes.com.au with details of your system (operating system version etc) and an explanation of the error you are experiencing.</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<B><P ALIGN="JUSTIFY">mmap</B>&#9;mSQL 2.0 requires a fully functional mmap implementation.  Some operating systems either provide no mmap support at all or provide a limited subset of mmap. At this point in time, mSQL cannot operate on these operating systems.  The most common operating systems displaying this problem are Digital Ultrix, Cray UNICOS and Linux versions earlier than 1.3 (newer versions of Linux are fine).</P>
<B><P ALIGN="JUSTIFY">dynamic loading</B>&#9;Some of the mSQL tools utilise dynamic loading of object modules (most notably the Lite and W3-mSQL tools).  The setup utility will try to determine how to perform dynamic loading on your platform automatically.  If you encounter link problems with references to functions such as dl_open then the automatic configuration has failed.  You can safely remove the dynamic loading functionality by editing the site.mm and removing the &quot;HAVE_DYNAMIC&quot; option.</P>
<B><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">Linux&#9;</B>Some distributions of Linux, including the Slackware distribution, do not include all the required C header files by default.  If you did not include the kernel sources when you installed your version of Linux you may not be able to compile the mSQL software. Installing the kernel sources will solve this problem.</P>
<B><P ALIGN="JUSTIFY">bitypes</B>&#9;On some systems, the compilation of mSQL will fail with errors relating to the bitypes.h header file.  This is commonly due to the installation of BIND 4.9 nameserver software.  BIND replaces some of your header files during installation but fails to re-install the bitypes.h and cdefs.h files.  The problem is solved by copying these header files from the compat/include directory of the BIND distribution to the /usr/include/sys directory of your system.</P>
<B><P ALIGN="JUSTIFY">Irix</B>&#9;Some installations of Irix include duplicate versions of several system routines in separate C libraries.  The setup utility will recognise these libraries and include them in the link process automatically.  This can cause errors relating to &quot;weak definitions&quot; and also unresolved symbols.  To overcome this problem, edit the site.mm file and remove anything included on the EXTRA_LIBS line (i.e. set it to &quot;EXTRA_LIBS=&quot;)</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767729">The mSQL Query Language</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The mSQL language offers a significant subset of the features provided by ANSI SQL. It allows a program or user to store, manipulate and retrieve data in table structures. It does not support some relational capabilities such as views and nested queries. Although it does not support all the relational operations defined in the ANSI specification, mSQL provides a significant subset of the ANSI SQL standard and is capable of supporting the vast majority of applications. </P>
<P ALIGN="JUSTIFY">The definitions and examples below depict mSQL key words in upper case, but no such restriction is placed on the actual queries. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767730">The Create Clause</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The create clause as supported by mSQL 2 can be used to create tables, indices, and sequences. The three valid constructs of the create clause are shown below: </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>CREATE TABLE table_name ( </P>
<P>col_name col_type [ not null ] </P>
<P>[ , col_name col_type [ not null ] ]** </P>
<P>) </P>
<P>&nbsp;</P>
<P>CREATE [ UNIQUE ] INDEX index_name ON table_name ( </P>
<P>field_name </P>
<P>[ , field_name ] ** </P>
<P>) </P>
<P>&nbsp;</P>
<P>CREATE SEQUENCE ON table_name [ STEP step_val ] [ VALUE initial_val ] </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><BR>
An example of the creation of a table is shown below: </P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>CREATE TABLE emp_details ( </P>
<P>first_name char(15) not null,</P>
<P>last_name char(15) not null,</P>
<P>comment text(50), </P>
<P>dept char(20), </P>
<P>emp_id int </P>
<P>) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><BR>
The available types are:- </P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" WIDTH=624>
<TR><TD WIDTH="13%" VALIGN="MIDDLE" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Type</B></FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY"> char (len)</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">String of characters (or other 8 bit data)</FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY"> text (len)</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">Variable length string of characters (or other 8 bit data) The defined length is used to indicate the expected average length of the data. Any data longer than the specified length will be split between the data table and external overflow buffers. <B>Note</B> : text fields are slower to access than char fields and cannot be used in an index nor in LIKE tests. </FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">int</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">Signed integer values</FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">real</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">Decimal or Scientific Notation real values</FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">uint</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">Unsigned integer values</FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">date</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">Date values in the format of DD-Mon-YYYY such as 1-Jan-1997</FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">time</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">Time values stored in 24 hour notation in the format of HH:MM:SS</FONT></TD>
</TR>
<TR><TD WIDTH="13%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">money</FONT></TD>
<TD WIDTH="87%" VALIGN="MIDDLE">
<FONT SIZE=2><P ALIGN="JUSTIFY">A numeric value with two fixed decimal places</FONT></TD>
</TR>
</TABLE>
</P>
<DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY"><BR>
The table structure shown in the example would benefit greatly from the creation of some <B>indices</B>. It is assumed that the <I>emp_id</I> field would be a unique value that is used to identify an employee. Such a field would normally be defined as the primary key. mSQL 2.0 has removed support for the primary key construct within the table creation syntax and replaced it with the more powerful and flexible indexing scheme. Similarly, a common query may be to access an employee based on the combination of the first and last names. A compound index (i.e. constructed from more than one field) would improve performance.  Naturally, such a compound index may have multiple entries with the same value (if more than one person called John Smith works for the same company) so a non-unique index would be required.  We could construct these indices using : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>CREATE UNIQUE INDEX idx1 ON emp_details (emp_id)<BR>
CREATE INDEX idx2 ON emp_details (first_name, last_name)</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><BR>
These indices will be used automatically whenever a query is sent to the database engine that uses those fields in its WHERE clause. The user is not required to specify any special values in the query to ensure the indices are used to increase performance. </P>
<P ALIGN="JUSTIFY"><BR>
<B>Sequences</B> provide a mechanism via which a sequence value can be maintained by the mSQL server. Sequences are a numeric value that can be used as serial numbers, staff identifiers, invoice numbers, or any other application that requires a unique numeric value.  Having the server maintain the index allows for atomic operations (such as getting the next sequence value) and removes the concerns associated with performing these operations in client applications.  A client application would need to send two queries (one to read the current value and one to update the value) which introduces a &quot;race condition&quot; and the potential for the same sequence value to be assigned to multiple items. </P>
<P ALIGN="JUSTIFY">A sequence is associated with a table and a table may contain at most one sequence. Once a sequence has been created it can be accessed by SELECTing the _seq system variable from the table in which the sequence is defined. For example </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>CREATE SEQUENCE ON test STEP 1 VALUE 5 <BR>
SELECT _seq FROM test </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The above CREATE operation would define a sequence on the table called <I>test</I> that had an initial value of 5 and would be incremented each time it is accessed (i.e. have a step of 1). The SELECT statement above would return the value 5. If the SELECT was issued again, a value of 6 would be returned. Each time the _seq field is selected from <I>test</I> the current value is returned to the caller and the sequence value itself is incremented. </P>
<P ALIGN="JUSTIFY">Using the STEP and VALUE options a sequence can be created that starts at any specified number and is increased or decreased by any specified value. The value of a sequence would decrease by 5 each time it was accessed if it was defined with a step of -5. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767731">The Drop Clause</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The Drop clause is used to remove a definition from the database. It is most commonly used to remove a table from a database but can also be used for removing several other constructs. In 2.0 it can be used to remove the definition of an index, a sequence, or a table. It should be noted that <I>dropping</I> a table or an index removes the data associated with that object as well as the definition.   Dropping a table removes any indices or sequences defined for the table.</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>The drop clause cannot be used to remove an entire database.  Dropping a database is achieved by using the msqladmin utility program that is included in the software distribution.</P>
<P ALIGN="JUSTIFY">The syntax of the drop clause as well as examples of its use are given below. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>DROP TABLE table_name<BR>
DROP INDEX index_name FROM table_name<BR>
DROP SEQUENCE FROM table_name </P>
<P>&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Examples of the use of the drop clause for removing an entire table, an index and a sequence are shown below.   </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>DROP TABLE emp_details<BR>
DROP INDEX idx1 FROM emp_details<BR>
DROP SEQUENCE FROM emp_details </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767732">The Insert Clause</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The insert clause is used to insert or add data to the database.  When inserting data you may either specify the fields for which you have provided data (if you are not providing data for every field in the data row) or you may omit the field names if you are providing data for every field.   If you do not specify the field names they will be used in the order in which they were defined - you must specify a value for every field if you use this form of the insert clause.  If you provide the field names then the number of data values provided must match the number of fields specified.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>INSERT INTO table_name [ ( column [ , column ] ** ) ] </P>
<P>VALUES ( value [ , value ] ** ) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">for example </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>INSERT INTO emp_details ( first_name, last_name, dept, salary) </P>
<P>VALUES ( 'David', 'Hughes', 'Development',12345.00) </P>
<P>INSERT INTO emp_details </P>
<P>VALUES ('David', 'Hughes', 'Development',12345.00) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767733">The Select Clause</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The select clause is used to extract data from the database.  It allows you to specify the particular fields you wish to retrieve and also a condition to identify the records or rows that are of interest.  The ANSI SQL standard defines two features that are not supported by mSQL.  The mSQL implementation of the select clause does not support</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
<P ALIGN="JUSTIFY"><LI>Nested selects </LI></P>
<P ALIGN="JUSTIFY"><LI>Implicit functions (e.g. count(), avg() ) </LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">It does however support: </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
<P ALIGN="JUSTIFY"><LI>Relational joins between multiple tables</LI></P>
<P ALIGN="JUSTIFY"><LI>Table aliases </LI></P>
<P ALIGN="JUSTIFY"><LI>DISTINCT row selection for returning unique values</LI></P>
<P ALIGN="JUSTIFY"><LI>ORDER BY clauses for sorting</LI></P>
<P ALIGN="JUSTIFY"><LI>Normal SQL regular expression matching </LI></P>
<P ALIGN="JUSTIFY"><LI>Enhanced regular expression matching including case insensitive and soundex</LI></P>
<P ALIGN="JUSTIFY"><LI>Column to Column comparisons in WHERE clauses </LI></P>
<P ALIGN="JUSTIFY"><LI>Complex conditions </LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">The formal definition of the syntax for mSQL's select clause is </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>SELECT [table.]column [ , [table.]column ]** </P>
<P>FROM table [ = alias] [ , table [ = alias] ]** </P>
<P>[ WHERE [table.] column OPERATOR VALUE </P>
<P>[ AND | OR [table.]column OPERATOR VALUE]** ]</P>
<P>[ ORDER BY [table.]column [DESC] [, [table.]column [DESC] ] </P>
<P>&nbsp;</P>
<P>OPERATOR can be &lt;, &gt;, =, &lt;=, =, &lt;&gt;, LIKE, RLIKE, CLIKE or SLIKE<BR>
VALUE can be a literal value or a column name </P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The condition used in the where statement of a select clause may contain '(' ')' to nest conditions or to focus on parts of the conditional evaluation.  e.g. "where (age &lt;20 or age &gt;30) and sex = 'male'" . </P>
<P ALIGN="JUSTIFY">A simple select that returns the first and last names of anybody employed in the finance department would be </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>SELECT first_name, last_name FROM emp_details </P>
<P>WHERE dept = 'finance' </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">To sort the returned data we would add an ORDER BY statement to the select clause.  mSQL supports sorting on multiple values in either ascending or descending order for each value.  If a direction is not specified it defaults to ascending order.  To sort the data from the previous query in ascending order by last_name and descending order by first_name we could use the query below.  Note that the two sorting values are separated by a comma and that the first_name field includes the DESC attribute to indicate we sorting is required in descending order.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=2><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>SELECT first_name, last_name FROM emp_details </P>
<P>WHERE dept = 'finance' </P>
<P>ORDER BY last_name, first_name DESC </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">A query such as the one presented above may return multiple of the same value.  If for example there were two people named John Smith working in the finance department the name John Smith would be returned twice from the query.  You may remove any duplicates from the returned data by providing the DISTINCT attribute with the query.  An example of using the DISTINCT attribute to remove duplicates from the above query is given below.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=2><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>SELECT DISTINCT first_name, last_name FROM emp_details </P>
<P>WHERE dept = 'finance' </P>
<P>ORDER BY last_name, first_name DESC </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">mSQL provides four regular expression operators for use in <I>where</I> comparisons. These operators may be used to perform &quot;fuzzy&quot; matching on the data if you do not know the exact value for which you are searching.  An example of such a search would be if you were looking for any employee with a last_name starting with Mc such as McCormack or McDonald.  In such a situation you cannot provide a complete value for the last_name field as you are only interested in part of the value.</P>
<P ALIGN="JUSTIFY">The standard SQL syntax provides a very simplistic regular expression capability that does not provide the power nor the flexibility of which UNIX programmers or users will be accustomed. mSQL supports the "standard" SQL regular expression syntax, via the LIKE operator, but also provides further functionality if it is required. The available regular expression operators are: </P>
</FONT><FONT SIZE=1><P ALIGN="JUSTIFY"> </P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><LI>LIKE - the standard SQL regular expression operator. </LI></P>
<P ALIGN="JUSTIFY"><LI>CLIKE - a standard LIKE operator that ignores case. </LI></P>
<P ALIGN="JUSTIFY"><LI>RLIKE - a complete UNIX regular expression operator. </LI></P>
<P ALIGN="JUSTIFY"><LI>SLIKE - a soundex matching operator (i.e. phonetic matching)</LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<B><P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Note</B> : CLIKE, RLIKE, and SLIKE are not features of standard SQL and may not be available in other implementations of the language.  If you choose to use them you may have problems porting your application to other database systems. They are, however, very convenient and powerful features of mSQL. </P>
<P ALIGN="JUSTIFY">LIKE and CLIKE utilise the regular expression syntax as specified in the ANSI SQL standard.  As mentioned above, the ANSI standard regular expression feature provides only a very simplistic implementation of regular expressions.  It provides for only single and multiple character wildcards.  It does not include enhanced features such as value ranges, value exclusions or value groups.  The syntax of the LIKE and CLIKE operators is provided in the following table.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=486>
<TR><TD WIDTH="15%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Operator</B></FONT></TD>
<TD WIDTH="85%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">_</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">matches any single character</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">matches 0 or more characters of any value </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">\</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">escapes special characters (e.g. '\%' matches % and '\\' matches \ ). All other characters match themselves</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=1><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Two examples of using the LIKE operator are provided below.  In the first we are searching for anyone in the finance department whose last name consists of any letter followed by 'ughes', such as Hughes.   The second example shows the query for the Mc example mentioned earlier in this section. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>SELECT first_name, last_name FROM emp_details </P>
<P>WHERE dept = 'finance' and last_name like '_ughes' </P>
<P>&nbsp;</P>
<P>SELECT first_name, last_name FROM emp_details</P>
<P>WHERE dept = finance and last_name like Mc%</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The RLIKE operator provides access to the power of the UNIX standard regular expression syntax. The UNIX regular expression syntax provides far greater functionality than SQL's LIKE syntax. The UNIX regex syntax does not use the '_' or '%' characters in the way SQL's regex does (as outlined above) and provides enhanced functionality such as grouping, value ranges, and value exclusion.  The syntax available in the RLIKE operator is shown in the table below.  Tutorials for using UNIX regular expression matching are available in the manual pages of any UNIX system (such as the manual pages for grep or ed).</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Because RLIKE utilises a complete UNIX regex implementation, the evaluation of a condition containing the RLIKE operator is quite complex.  The performance of searches using the RLIKE operator will be slower than those using the LIKE or CLIKE operator.  You should only use the RLIKE operator if you cannot achieve your desired matching using the more simplistic LIKE or CLIKE operators.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=486>
<TR><TD WIDTH="15%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Operator</B></FONT></TD>
<TD WIDTH="85%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">.</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The dot character matches any single character</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">^</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">When used as the first character in a regex, the caret character forces the match to start at the first character of the string</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">$</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">When used as the last character in a regex, the dollar sign forces the match to end at the last character of the string</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">[ ]</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">By enclosing a group of single characters within square brackets, the regex will match a single character from the group of characters. If the ']' character is one of the characters you wish to match you may specify it as the first character in the group without closing the group (e.g. '[]abc]' would match any single character that was either ']', 'a', 'b', or 'c'). Ranges of characters can be specified within the group using the 'first-last' syntax (e.g. '[a-z0-9]' would match any lower case letter or a digit). If the first character of the group is the '^' character the regex will match any single character that is <B>not</B> contained within the group.</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">*</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">If any regex element is followed by a '*' it will match <B>zero or more</B> instances of the regular expression.  To match any string of characters you would use .* and to match any string of digits you would use [0-9]*</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">The SLIKE operator provides soundex matching of values (i.e. one value sounds like another value).  It does not use an explicit syntax in the same way as the other LIKE operators.  You simply provide the word you wish to match.  If you wished to search for any name that sounded like Hughes, such as Hues you could use SLIKE Hughes.</P>
<B><P ALIGN="JUSTIFY">Relational joining</B> is one of the most powerful features of a relational query language.  The concept of &quot;joining&quot; relates to &quot;merging&quot; multiple database tables together and extracting fields from the merged result.  As an example, if you had two tables defined, one containing employee details and another containing a list of all current, you may wish to extract a list of the projects that each employee was working on.  Rather than duplicating the employee details in the projects table you could simply include the employees staff ID number in the projects table and use a join to extract the first and last names.</P>
<P ALIGN="JUSTIFY">The query below is an example of such an operation.  The logic behind the query is that we want to extract the first and last names of the employee, plus the name of the project on which the employee is working.  We can identify which combinations of the merged table we are looking for as they will have a common value for the employees staff ID value.  Because we are referencing multiple tables in the query, we must include the table name for each field when it is included in the query (e.g. emp_details.first_name rather than just first_name)</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>SELECT emp_details.first_name, emp_details.last_name, project_details.project </P>
<P>FROM emp_details, project_details </P>
<P>WHERE emp_details.emp_id = project_details.emp_id </P>
<P>ORDER BY emp_details.last_name, emp_details.first_name </P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>It is important to understand the inner workings of a join.  If we are joining table A with table B, a merged row will be created for all possible combinations of the rows of both tables.  If table A contains only two rows and table B contains 10 rows, then 20 merged rows will be generated and evaluated against the <I>where</I> condition.  If no <I>where</I> condition is specified then all 20 rows will be returned.  If this example is extended so that table A contained 1,000 rows and table B contained 2,500 rows then the result would be 1,000 * 2,500 merged rows (thats two and a half million rows!). Whenever a join is used there should normally be a common value in both tables (such as the employee ID in our example) and the condition must include a direct comparison between these two fields to ensure that the result set is limited to only the desired results.  </P>
<P ALIGN="JUSTIFY">mSQL places no restriction on the number of tables "joined" during a query so if there were 15 tables all containing information related to an employee ID in some manner, and each table included the employee ID field to identify the employee, data from each of those tables could be extracted, by a single query. As mentioned before, a key point to note regarding joins is that you must qualify all field names with a table name. Remember that you must qualify every column name as soon as you access more than one table in a single <I>select</I>. </P>
<P ALIGN="JUSTIFY">mSQL also supports table aliases so that you can perform a join of a table onto itself. This may appear to be an unusual thing to do but it is a very powerful feature if the rows within a single table relate to each other in some way. An example of such a table could be a list of people including the names of their parents. In such a table there would be multiple rows with a parent/child relationship. Using a table alias you could find out any grandparents contained in the table using the query below.  The logic is to find any person who is the parent of someones parent. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>SELECT t1.parent, t2.child from parent_data=t1, parent_data=t2 </P>
<P>WHERE t1.child = t2.parent </P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The table aliases t1 and t2 both point to the same table (parent_data in this case) and are treated as two different tables that just happen to contain exactly the same data.  Like any other join, the possible result set size is the multiplication of the number of rows in each table.  If a table is joined with itself, this equates to N<SUP>2</SUP> rows where N is the number of rows in the original table.  Care must be taken to ensure that the result set is limited by the condition specified otherwise the query can take a very long time to complete and has the potential to fill your disk drive with temporary data as the query is processed.</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767734">The Delete Clause</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The SQL DELETE clause is used to remove one or more entries from a database table. The selection of rows to be removed from the table is based on the same <I>where</I> statement as used by the SELECT clause. In the SELECT clause, the <I>where</I> condition is used to identify the rows to be extracted from the database.  In the DELETE clause, the <I>where</I> condition identifies the rows that are to be deleted from the database.  As with all SQL queries, if no where condition is provided, then the query applies to every row in the table and the entire contents of the table will be deleted.  The syntax for mSQL's delete clause is shown below</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>DELETE FROM table_name </P>
<P>WHERE column OPERATOR value </P>
<P>[ AND | OR column OPERATOR value ]** </P>
<P><BR>
OPERATOR can be &lt;, &gt;, =, &lt;=, =, &lt;&gt;, LIKE, RLIKE, CLIKE, or SLIKE</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">An example of deleting a specific employee (identified by the employee ID number of the person) and also deleting every employee within a particular salary range is given below.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>DELETE FROM emp_details WHERE emp_id = 12345 </P>
<P>DELETE FROM emp_details WHERE salary &gt; 20000 and salary &lt; 30000</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767735">The Update Clause</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The SQL update clause is used to modify data that is already in the database. The operation is carried out on one or more rows as specified by the <I>where</I> construct. If the condition provided in the where construct matches multiple rows in the database table then each matched row will be updated in the same way.  The value of any number of fields in the matched rows can be updated. The syntax supported by mSQL is shown below.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>UPDATE table_name SET column=value [ , column=value ]** </P>
<P>WHERE column OPERATOR value </P>
<P>[ AND | OR column OPERATOR value ]**</P>
<P>OPERATOR can be &lt;, &gt;, =, &lt;=, =, &lt;&gt;, LIKE, RLIKE, CLIKE or SLIKE</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">For example </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>UPDATE emp_details SET salary=30000 WHERE emp_id = 1234 </P>
<P>UPDATE emp_details SET salary=35000, dept=Development where emp_id = 1234</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767736">C Programming API</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Included in the distribution is the mSQL API library, libmsql.a. The API allows any C program to communicate with the database engine. The API functions are accessed by including the msql.h header file into your program and by linking against the mSQL library (using -lmsql as an argument to your C compiler). The library and header file will be installed by default into /usr/local/ Hughes/lib and /usr/local/Hughes/include respectively.   An example compilation of a client application (my_app.c in this case) is shown below.  The header file and API library are assumed to be in the default installation directory. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>cc c I/usr/local/Hughes/include  my_app.c</P>
<P>cc o my_app  my_app.c  -L/usr/local/Hughes/lib  -lmsql</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Some versions of UNIX, usually those derived from SystemV, do not include the TCP/IP networking functions in the standard C library.  The mSQL API library includes calls to the networking functions to facilitate the client/server nature of the API.  On machines that do not include the networking functions in the standard C library, the compilation illustrated above would fail due to &quot;unresolved externals&quot; with reference to function names such as socket( ) and gethostbyname( ).  If this occurs then the networking code must also be linked with the application.  This is usually achieved by adding &quot;-lsocket lnsl&quot; to the link command as shown below.  If you continue to have problems, please consult the &quot;socket&quot; and &quot;gethostbyname&quot; manual pages of your system to determine the libraries you have to include in your link statement.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>cc c I/usr/local/Hughes/include  my_app.c</P>
<P>cc o my_app  my_app.c  -L/usr/local/Hughes/lib  -lmsql lsocket lnsl</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Like the mSQL engine, the API supports debugging via the MSQL_DEBUG environment variable. The API currently supports three debugging modules: query, api, and malloc. Enabling "query" debugging will cause the API to print the contents of queries as they are sent to the server. The "api" debug module causes internal information, such as connection details, to be printed. Details about the memory used by the API library can be obtained via the "malloc" debug module. Information such as the location and size of malloced blocks and the addresses passed to free() will be generated. Multiple debug modules can be enabled by setting MSQL_DEBUG to a colon separated list of module names. For example setenv MSQL_DEBUG api:query </P>
<P ALIGN="JUSTIFY">The API has changed slightly from the original mSQL API.  Please ensure that you check the semantics and syntax of the functions before you use them.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767737">Query Related Functions</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlConnect()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int  msqlConnect ( host ) </P>
<P>char&#9; * host ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">msqlConnect() forms an interconnection with the mSQL engine. It takes as its only argument the name or IP address of the host running the mSQL server. If NULL is specified as the host argument, a connection is made to a server running on the localhost using the UNIX domain socket /dev/msqld. If an error occurs, a value of -1 is returned and the external variable msqlErrMsg will contain an appropriate text message. This variable is defined in "msql.h". </P>
<P ALIGN="JUSTIFY">If the connection is made to the server, an integer identifier is returned to the calling function. This value is used as a handle for all other calls to the mSQL API. The value returned is in fact the socket descriptor for the connection. By calling msqlConnect() more than once and assigning the returned values to separate variables, connections to multiple database servers can be maintained simultaneously. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>In previous versions of mSQL, the MSQL_HOST environment variable could be used to specify a target machine if the host parameter was NULL. This is no longer the case. It should also be noted that communicating with the server via UNIX sockets rather than TCP/IP sockets increases performance greatly.  If you are communicating with a server on the same machine as the client software you should always specify NULL as the hostname.  Using &quot;localhost&quot; or the name of the local machine will force the use of TCP/IP and degrade performance.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlSelectDB()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlSelectDB ( sock , dbName ) </P>
<P>int &#9;sock ; </P>
<P>char &#9;* dbName ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Prior to submitting any queries, a database must be chosen. msqlSelectDB() instructs the engine which database is to be accessed. msqlSelectDB() is called with the socket descriptor returned by msqlConnect() and the name of the desired database. A return value of -1 indicates an error with msqlErrMsg set to a text string representing the error. msqlSelectDB() may be called multiple times during a program's execution. Each time it is called, the server will use the specified database for future accesses. By calling msqlSelectDB() multiple times, a program can switch between different databases during its execution. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlQuery()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlQuery ( sock , query ) </P>
<P>int &#9;sock ; </P>
<P>char &#9;* query ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>A query in SQL terminology is not the same as a query in the English language.  In English, the word query relates to asking a question whereas in SQL a query is a valid SQL command.  It is a common mistake that people believe that the msqlQuery function can only be used to submit SELECT commands to the database engine.  In reality, msqlQuery can be used for any valid mSQL command including SELECT, DELETE, UPDATE etc.</P>
<P ALIGN="JUSTIFY">Queries are sent to the engine over the connection associated with sock as plain text strings using msqlQuery(). As with previous releases of mSQL, a returned value of -1 indicates an error and msqlErrMsg will be updated to contain a valid error message. If the query generates output from the engine, such as a SELECT statement, the data is buffered in the API waiting for the application to retrieve it. If the application submits another query before it retrieves the data using msqlStoreResult(), the buffer will be overwritten by any data generated by the new query. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>In previous versions of mSQL, the return value of msqlQuery() was either -1 (indicating an error) or 0 (indicating success). mSQL 2 adds to these semantics by providing more information back to the client application via the return code. If the return code is greater than 0, not only does it imply success, it also indicates the number of rows "touched" by the query (i.e. the number of rows returned by a SELECT, the number of rows modified by an update, or the number of rows removed by a delete). </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlStoreResult()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_result * msqlStoreResult ( ) </P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Data returned by a SELECT query must be stored before another query is submitted or it will be removed from the internal API buffers. Data is stored using the msqlStoreResult() function which returns a result handle to the calling routines. The result handle is a pointer to a m_result structure and is passed to other API routines when access to the data is required. Once the result handle is allocated, other queries may be submitted. A program may have many result handles active simultaneously.   See also msqlFreeResult( ).</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFreeResult()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>void msqlFreeResult ( result ) </P>
<P>m_result &#9;* result ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">When a program no longer requires the data associated with a particular query result, the data must be freed using msqlFreeResult(). The result handle associated with the data, as returned by msqlStoreResult() is passed to msqlFreeResult() to identify the data set to be freed. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFetchRow()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_row msqlFetchRow ( result ) </P>
<P>m_result &#9;* result ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The individual database rows returned by a select are accessed via the msqlFetchRow() function. The data is returned in a variable of type m_row which contains a char pointer for each field in the row. For example, if a select statement selected 3 fields from each row returned, the value of the three fields would be assigned to elements [0], [1], and [2] of the variable returned by msqlFetchRow(). A value of NULL is returned when the end of the data has been reached. See the example at the end of this section for further details. Note: a NULL value in the database is represented as a NULL pointer in the row. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlDataSeek()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>void msqlDataSeek ( result , pos ) </P>
<P>m_result &#9;* result ; </P>
<P>int &#9;pos ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The m_result structure contains a client side "cursor" that holds information about the next row of data to be returned to the calling program. msqlDataSeek() can be used to move the position of the data cursor. If it is called with a position of 0, the next call to msqlFetchRow() will return the first row of data returned by the server. The value of pos can be anywhere from 0 (the first row) and the number of rows in the table. If a seek is made past the end of the table, the next call to msqlFetchRow() will return a NULL. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlNumRows()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlNumRows ( result ) </P>
<P>m_result &#9;* result ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The number of rows returned by a query can be found by calling msqlNumRows() and passing it the result handle returned by msqlStoreResult(). The number of rows of data sent as a result of the query is returned as an integer value. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>If no data is matched by a <I>select</I> query, msqlNumRows() will indicate that the result table has 0 rows.  Note: earlier versions of mSQL returned a NULL result handle if no data was found. This has been simplified and made more intuitive by returning a result handle with 0 rows of result data.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFetchField()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_field * msqlFetchField ( result ) </P>
<P>m_result &#9;* result ; </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Along with the actual data rows, the server returns information about the data fields selected. This information is made available to the calling program via the msqlFetchField() function. Like msqlFetchRow(), this function returns one element of information at a time and returns NULL when no further information is available. The data is returned in a m_field structure which contains the following information:- </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>typedef struct {</P>
<P>char&#9;* name ;&#9;&#9;/* name of field */</P>
<P>char&#9;* table ;&#9;&#9;/* name of table */</P>
<P>int&#9;type ;&#9;&#9;/* data type of field */</P>
<P>int&#9;length ,&#9;&#9;/* length in bytes of field */</P>
<P>int&#9;flags ;&#9;&#9;/* attribute flags */</P>
<P>&#9;} m_field;</P>
<P>&nbsp;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">Possible values for the type field are defined in msql.h.  Please consult the header file if you wish to interpret the value of the type or flags field of the m_field structure. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFieldSeek()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>void msqlFieldSeek ( result , pos )</P>
<P>m_result &#9;* result ;</P>
<P>int &#9;pos ;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&#9;</P>
<P ALIGN="JUSTIFY">The result structure includes a "cursor" for the field data. Its position can be moved using the msqlFieldSeek() function. See msqlDataSeek() for further details.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlNumFields()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlNumFields ( result )</P>
<P>m_result * result ;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The number of fields returned by a query can be ascertained by calling msqlNumFields() and passing it the result handle. The value returned by msqlNumFields() indicates the number of elements in the data vector returned by msqlFetchRow(). It is wise to check the number of fields returned because, as with all arrays, accessing an element that is beyond the end of the data vector can result in a segmentation fault.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlClose()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlClose ( sock )</P>
<P>int&#9;sock ;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The connection to the mSQL engine can be closed using msqlClose(). The function must be called with the connection socket returned by msqlConnect() when the initial connection was made.  msqlClose() should be called by an application when it no longer requires the connection to the database.  If the connection isnt closed, valuable resources, such as network sockets or file descriptors, can be wasted.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767738">Schema Related Functions</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListDBs()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_result * msqlListDBs ( sock ) </P>
<P>int &#9;sock ;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&#9;</P>
<P ALIGN="JUSTIFY">A list of the databases known to the mSQL engine can be obtained via the msqlListDBs() function. A result handle is returned to the calling program that can be used to access the actual database names. The individual names are accessed by calling msqlFetchRow() passing it the result handle. The m_row data structure returned by each call will contain one field being the name of one of the available databases. As with all functions that return a result handle, the data associated with the result must be freed when it is no longer required using msqlFreeResult().  Failure to do so will waste memory.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListTables()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_result * msqlListTables ( sock )</P>
<P>int&#9;sock ;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Once a database has been selected using msqlInitDB(), a list of the tables defined in that database can be retrieved using msqlListTables(). As with msqlListDBs(), a result handle is returned to the calling program and the names of the tables are contained in data rows where element [0] of the row is the name of one table in the current database. The result handle must be freed when it is no longer needed by calling msqlFreeResult().  If msqlListTables is called before a database has been chosen using msqlSelectDB an error will be generated.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListFields()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_result * msqlListFields ( sock , tableName ) ;</P>
<P>&#9;int &#9;sock ;</P>
<P>&#9;char &#9;* tableName;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Information about the fields in a particular table can be obtained using msqlListFields(). The function is called with the name of a table in the current database as selected using msqlSelectDB() and a result handle is returned to the caller. Unlike msqlListDBs() and msqlListTables(), the field information is contained in field structures rather than data rows. It is accessed using msqlFetchField(). The result handle must be freed when it is no longer needed by calling msqlFreeResult().  As with msqlListTables, msqlListFields will return an error if it is called prior to a database being chosen using the msqlSelectDB function.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListIndex()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>m_result * msqlListIndex ( sock , tableName , index ) ;</P>
<P>&#9;int &#9;sock ;</P>
<P>&#9;char &#9;* tableName;</P>
<P>&#9;char &#9;* index;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The structure of a table index can be obtained from the server using the msqlListIndex() function.  The result table returned contains one field. The first row of the result contains the symbolic name of the index mechanism used to store the index.  Rows 2 and onwards contain the name of the fields that comprise the index.  </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">An example of the data returned by msqlListIndex is shown below.  The example shows the result of calling msqlListIndex on a compound index.  The index is defined as an AVL Tree index and is based on the values of the fields first_name and last_name.  Currently the only valid index type is avl signifying a memory mapped AVL tree index.  Further index schemes will be added to mSQL in the future.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>row[0]</P>
<P>avl</P>
<P>first_name</P>
<P>last_name</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767739">Date &amp; Time Related Functions</A></P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlTimeToUnixTime()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>time_t  msqlTimeToUnixTime( msqltime )</P>
<P>&#9;char &#9;* msqltime;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlTimeToUnixTime( ) converts an mSQL time value to a standard UNIX time value.  The mSQL time value must be a character string in the 24 hour format of &quot;HH:MM:SS&quot; and the returned value will be the number of seconds since 1 Jan 1970 (the normal UNIX format).</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlUnixTimeToTime()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * msqlUnixTimeToTime( clock )</P>
<P>&#9;time_t&#9;clock;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlUnixTimetoTime( ) converts a UNIX time value (seconds since the UNIX epoch) into a character string representing the same time in mSQL time format (i.e. &quot;HH:MM:SS&quot; 24 hour format).  The returned string is statically declared in the API so you must make a copy of it before you call the function again.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlDateToUnixTime()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>time_t  msqlDateToUnixTime( msqldate )</P>
<P>&#9;char &#9;* msqldate;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlDateToUnixDate( ) converts an mSQL date format string into a UNIX time value.  The mSQL date format is &quot;DD-Mon-YYYY&quot; (for example &quot;12-Jun-1997&quot;) while the returned value will be the number of seconds since the UNIX epoch.  The mSQL date routines will assume the 20<SUP>th</SUP> century if only 2 digits of the year value are presented.  Although the valid range of mSQL dates is 31<SUP>st</SUP> Dec 4096bc to the 31<SUP>st</SUP> Dec 4096, the UNIX format cannot represent dates prior to the 1<SUP>st</SUP> Jan 1970.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">msqlUnixTimeToDate()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * msqlUnixTimeToDate( clock )</P>
<P>&#9;time_t&#9;clock;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlUnixTimeToDate( ) converts a standard UNIX time value to an mSQL date string.  The time value is specified as seconds since the UNIX epoch ( 1<SUP>st</SUP> Jan 1970) while the mSQL date string will contain the date formatted as &quot;DD-Mon-YYYY&quot; (e.g. &quot;12-Jun-1997&quot;).  A convenient use of this function is to determine the mSQL date value for the current day using the following C code example.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>clock = time( );</P>
<P>date = msqlUnixTimeToDate( clock );</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlSumTimes()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * msqlSumTimes ( time1, time2 )</P>
<P>&#9;char &#9;* time1,</P><DIR>
<DIR>

<P>*time2;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The msqlSumTimes( ) routine provides a mechanism for performing addition between two mSQL time formatted strings.  A literal addition of the values is returned to the calling routine in mSQL time format. As an example, calling msqlSumTimes with the values &quot;1:30:25&quot; and &quot;13:15:40&quot; would return &quot;14:46:05&quot;.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlDateOffset()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * msqlDateOffset( date, dOff, mOff, yOff )</P>
<P>&#9;char &#9;* date;</P>
<P>&#9;int&#9;dOff,</P>
<P>&#9;&#9;mOff,</P>
<P>&#9;&#9;yOff</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The msqlDateOffset( ) function allows you to generate an mSQL date string that is a specified period before or after a given date.  This routine will determine the correct date based on the varying days of month.  It is also aware of leap years and the impact they have on date ranges.  The new date is calculated using the specified date and an offset value for the day, month and year.  The example below would determine tomorrow's date</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>clock = time( );</P>
<P>today = msqlUnixTimeToDate( clock );</P>
<P>tomorrow = msqlDateOffset( today , 1 , 0 , 0 );</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlDiffTimes()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * msqlDiffTimes( time1, time2 )</P>
<P>&#9;char &#9;* time1,</P><DIR>
<DIR>

<P>*time2;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To determine the time difference between two time values, the msqlDiffTimes( ) function can be used. The two time values must be mSQL time formatted text strings and the returned value is also an mSQL time string.  A restriction is placed on the times in that time1 must be less than time2.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlDiffDates()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlDiffDates( date1, date2 )</P>
<P>&#9;char &#9;* date1,</P><DIR>
<DIR>

<P>* date2;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The msqlDiffDates( ) function can be used to determine the number of days between two dates.  Date1 must be less than date2 and the two dates must be valid mSQL date formatted strings.  In conjunction with the msqlDiffTimes( ) function it is possible to determine a complete time difference between two pairs of times and dates.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767740">Miscellaneous Functions</A></P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlLoadConfigFile()</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlLoadConfigFile( file )</P>
<P>&#9;char &#9;* file;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The msqlLoadConfigFile( ) function can be used to load a non-default configuration file into your client application.  The configuration file can include information such as the TCP/IP and UNIX ports on which the desired mSQL server will be running.  The file to be loaded is determined by the value of the file parameter.  If the value of the parameter is <I>new</I>, the msqlLoadConfigFile( ) function would search for the file in the following places (and in the order specified).</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>Inst_Dir/new</P>
<P>Inst_Dir/new.conf</P>
<P>new</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">That is, if a file called "new" exists in the installation directory, it is loaded.  Otherwise, an attempt will be made to load a file called new.conf from the installation directory.  If that fails, the filename specified is assumed to be a complete, absolute pathname and an attempt to open the file is made.  On failure, the function will return a value of 1, otherwise a value of 0 is returned.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767741">System Variables</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Mini SQL 2.0 includes internal support for system variables (often known as pseudo fields or pseudo columns). These variables can be accessed in the same way that normal table fields are accessed although the information is provided by the database engine itself rather than being loaded from a database table. System variables are used to provide access to server maintained information or meta data relating to the databases. </P>
<P ALIGN="JUSTIFY">System variables may be identified by a leading underscore in the variable name. Such an identifier is not normally valid in mSQL for table or field names. Examples of the supported system variables and uses for those variables are provided below. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767742">_rowid</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The _rowid system variable provides a unique row identifier for any row in a table. The value contained in this variable is the internal record number used by the mSQL engine to access the table row. It may be included in any query to uniquely identify a row in a table. An example of the use of the _rowid system variable is shown below.</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>select _rowid, first_name, last_name from emp_details </P>
<P>where last_name = 'Smith' </P>
<P>&nbsp;</P>
<P>update emp_details set title = 'IT Manager' </P>
<P>where _rowid = 57 </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The query optimiser is capable of utilising _rowid values to increase the performance of database accesses. In the second example query above, only one row (the row with the internal record ID of 57) would be accessed. This is in contrast to a sequential search through the database looking for that value which may result in only one row being modified but every row being accessed. Using the _rowid value to constrain a search is the fastest access method available in mSQL 2.0. As with all internal access decisions, the decision to base the table access on the _rowid value is automatic and requires no action by the programmer or user other than including the _rowid variable in the <I>where</I> clause of the query. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>The rowid of a table row is intended to be used for &quot;in place&quot; updates.  An example of such an update is the query above.  The rowid can be used when there is no other way to identify a particular row (e.g. there are two people called John Smith and staff identifiers are not being used).  It is not to be used as a substitute for an application maintained key or index.  Applications should use sequences if they wish to use server maintained unique values.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767743">_timestamp</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The _timestamp system variable contains the time at which a row was last modified. The value, although specified in the standard UNIX time format (i.e. seconds since the epoch), is not intended for interpretation by application software. The value is intended to be used as a point of reference via which an application may determine if a particular row was modified before or after another table row. The application should not try to determine an actual time from this value as the internal representation used may change in a future release of mSQL. </P>
<P ALIGN="JUSTIFY">The primary use for the _timestamp system variable will be internal to the mSQL engine. Using this information, the engine may determine if a row has been modified after a specified point in time (the start of a transaction, for example). It may also use this value to synchronise a remote database for database replication. Although neither of these functions is currently available, the presence of a row timestamp is the first step in the implementation. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">Example queries showing possible uses of the _timestamp system variable are show below.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>select first_name, _timestamp from emp_details </P>
<P>&#9;where first_name like '%fred%' order by _timestamp </P>
<P>&nbsp;</P>
<P>select * from emp_details where _timestamp 88880123 </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767744">_seq</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The _seq system variable is used to access the current sequence value of the table from which it is being selected. The current sequence value is returned and the sequence is updated to the next value in the sequence (see the CREATE definition in the Language Specification section for more information on sequences).  Once the sequence value has been read from the server using a select statement, the value can be inserted into &quot;normal&quot; fields of a table as a unique index value such as a serial number or staff identifier.</P>
<P ALIGN="JUSTIFY">An example query using _seq system variable is shown below. </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>select _seq from staff  </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767745">_sysdate</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The server can provide a central standard for the current date. If selected from any table, the _sysdate system variable will return the current date on the server machine using the mSQL date format of DD-Mon-YYYY.</P>
<P ALIGN="JUSTIFY">An example query using _sysdate system variable is shown below. </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>select _sysdate from staff </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767746">_systime</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The server can provide a central standard for the current time. If selected from any table, the _systime system variable will return the current time on the server machine using the mSQL time format of HH:MM:SS.</P>
<P ALIGN="JUSTIFY">An example query using _systime system variable is shown below. </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>select _systime from staff </P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767747">_user</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">By selecting the _user system variable from any table, the server will return the username of the user who submitted the query. </P>
<P ALIGN="JUSTIFY">An example query using _user system variable is shown below.</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>select _user from staff </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767748">Standard Programs and Utilities</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The mSQL distribution contains several programs and utilities to allow you to use and manage your databases.  The tools provided allow you to communicate with the database server, import data, export data, submit queries and view your database structures.  The sections below provide detailed descriptions on the various tools provided in the distribution.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767749">The monitor  msql</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Usage</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msql [-h host] [-f confFile] database </P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Options</P></DIR>
</DIR>
</DIR>
</B></FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-h</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a remote hostname or IP address on which the mSQL server is running. The default is to connect to a server on the localhost using a UNIX domain socket rather than TCP/IP (which gives better performance).</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-f</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a non-default configuration file to be loaded. The default action is to load the standard configuration file located in INST_DIR/msql.conf (usually /usr/local/Hughes/msql.conf). Please see the msqlLoadConfigFile entry in the API section of this manual to understand the method used to select the config file from the specified file name.</FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT FACE="Arial"><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Description</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The mSQL monitor is an interactive interface to the mSQL server. It allows you to submit SQL commands directly to the server. Any valid mSQL syntax can be entered at the prompt provided by the mSQL monitor.  For example, by typing a &quot;create table&quot; clause at the mSQL monitor prompt you can instruct the database server to create the specified table.  The mSQL monitor is intended to be used as a mechanism for creating your database tables and for submitting ad-hoc SQL queries to the server.  It is not intended to be used for client application development other than for testing queries before they are coded into your applications.</P>
<P ALIGN="JUSTIFY">Control of the monitor itself is provided by four internal commands. Each command is comprised of a backslash followed by a single character. The available commands are </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">\q</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Quit (also achieved by entering Control-D)</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">\g</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Go (Send the query to the server)</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">\e</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Edit (Edit the previous query)</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">\p</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Print (Print the query buffer)</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY"><A NAME="_Toc393767750">Schema viewer  relshow</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Usage</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">relshow [-h host] [-f confFile] [database [rel [idx] ] ] </P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Options</P></DIR>
</DIR>
</DIR>
</B></FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-h</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a remote hostname or IP address on which the mSQL server is running. The default is to connect to a server on the localhost using a UNIX domain socket rather than TCP/IP (which gives better performance).</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-f</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a non-default configuration file to be loaded. The default action is to load the standard configuration file located in INST_DIR/msql.conf (usually /usr/local/Hughes/msql.conf). Please see the msqlLoadConfigFile entry in the API section of this manual to understand the method used to select the config file from the specified file name.</FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT FACE="Arial"><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Description</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Relshow is used to display the structure of the contents of mSQL databases. If no arguments are given, relshow will list the names of the databases currently defined. If a database name is given it will list the tables defined in that database. If a table name is also given then it will display the structure of the table (i.e. field names, types, lengths etc). </P>
<P ALIGN="JUSTIFY">If an index name is provided along with the database and table names, relshow will display the structure of the specified index including the type of index and the fields that comprise the index. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767751">Admin program - msqladmin</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Usage</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqladmin [-h host] [-f confFile] [-q] Command </P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Options</P></DIR>
</DIR>
</DIR>
</B></FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-h</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a remote hostname or IP address on which the mSQL server is running. The default is to connect to a server on the localhost using a UNIX domain socket rather than TCP/IP (which gives better performance).</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-f</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a non-default configuration file to be loaded. The default action is to load the standard configuration file located in INST_DIR/msql.conf (usually /usr/local/Hughes/msql.conf). Please see the msqlLoadConfigFile entry in the API section of this manual to understand the method used to select the config file from the specified file name.</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-q</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Put msqladmin into quiet mode. If this flag is specified, msqladmin will not prompt the user to verify dangerous actions (such as dropping a database). </FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT FACE="Arial"><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Description</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqladmin is used to perform administrative operations on an mSQL database server. Such tasks include the creation of databases, performing server shutdowns, etc. The available commands for msqladmin are </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">create db_name</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Creates a new database called db_name.</FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">drop db_name</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Removes the database called db_name from the server. This will also delete all data contained in the database! </FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">shutdown</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Terminates the mSQL server. </FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">reload</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Forces the server to reload ACL information. </FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">version</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Displays version and configuration information about the currently running server. </FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">stats</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Displays server statistics. </FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">copy fromDB toDB</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Copies the contents of the database specified as the fromDB into a newly created database called toDB.  If the toDB already exists an error will be returned.  This command provides a simple mechanism for creating a backup copy of a data for use as a test or development environment.</FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">move fromDB toDB</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Renames an existing database called fromDB to toDB.  The data is not modified in any way.</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<B><P ALIGN="JUSTIFY"><IMG SRC="Image2.gif" WIDTH=57 HEIGHT=47>Note :</B> most administrative functions can only be executed by the user specified in the run-time configuration as the admin user. They can also only be executed from the host on which the server process is running (e.g. you cannot shutdown a remote server process). </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767752">Data dumper - msqldump</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Usage</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqldump [-h host] [-f confFile] [-c] [-v] database [table] </P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Options</P></DIR>
</DIR>
</DIR>
</B></FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="10%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-h</FONT></TD>
<TD WIDTH="90%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a remote hostname or IP address on which the mSQL server is running. The default is to connect to a server on the localhost using a UNIX domain socket rather than TCP/IP (which gives better performance).</FONT></TD>
</TR>
<TR><TD WIDTH="10%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-f</FONT></TD>
<TD WIDTH="90%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a non-default configuration file to be loaded. The default action is to load the standard configuration file located in INST_DIR/msql.conf (usually /usr/local/Hughes/msql.conf). Please see the msqlLoadConfigFile entry in the API section of this manual to understand the method used to select the config file from the specified file name.</FONT></TD>
</TR>
<TR><TD WIDTH="10%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-c</FONT></TD>
<TD WIDTH="90%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Include column names in INSERT commands generated by the dump. </FONT></TD>
</TR>
<TR><TD WIDTH="10%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-v</FONT></TD>
<TD WIDTH="90%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Run in verbose mode. This will display details such as connection results, etc. </FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT FACE="Arial"><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Description</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqldump produces an ASCII text file containing valid SQL commands that will recreate the table or database dumped when piped through the mSQL monitor program. The output will include all CREATE TABLE commands required to recreate the table structures, CREATE INDEX commands to recreate the indices, and INSERT commands to populate the tables with the data currently contained in the tables.  If sequences are defined on any of the tables being dumped, a CREATE SEQUENCE command will be generated to ensure the sequence is reset to its current value.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767753">Data exporter - msqlexport</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Usage</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlexport [-h host] [-f conf] [-v] [-s Char] [-q Char] [-e Char] database table </P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Options</P></DIR>
</DIR>
</DIR>
</B></FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-h</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a remove hostname or IP address on which the mSQL server is running. The default is to connect to a server on the localhost using a UNIX domain socket rather than TCP/IP (which gives better performance).</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-f</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a non-default configuration file to be loaded. The default action is to load the standard configuration file located in INST_DIR/msql.conf (usually /usr/local/Hughes/msql.conf). Please see the msqlLoadConfigFile entry in the API section of this manual to understand the method used to select the config file from the specified file name.</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-v</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Verbose mode.</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-s</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Use the character Char as the separation character. The default is a comma. </FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-q</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Quote each value with the specified character.</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-e</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Use the specified Char as the escape character. The default is \</FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT FACE="Arial"><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Description</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlexport produces an ASCII export of the data from the specified table. The output produced can be used as input to other programs such as spreadsheets. It has been designed to be as flexible as possible. The user may specify the character to use to separate the fields, the character to use to escape the separator character if it appears in the data, and whether the data should be quoted and if so what character to use as the quote character.  The output is sent to stdout with one data row per line. </P>
<P ALIGN="JUSTIFY">An example use of msqlexport would be to create a Comma Separated Values (CSV) file to be imported into a popular spreadsheet application such as Microsoft Excel.  The CSV format uses a comma to separate data fields and quotation marks to quote the individual values.  If a value contains a quotation mark, it is escaped by prefixing it with another quotation mark. To generate a CSV representation of a table called staff in the company database, the msqlexport command below would be used.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>msqlexport s ,  q &quot;  e &quot;  company staff</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767754">Data importer - msqlimport</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Usage</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlimport [-h host] [-f conf] [-v] [-s Char] [-q Char] [-e Char] database table </P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Options</P></DIR>
</DIR>
</DIR>
</B></FONT>
<P ALIGN="RIGHT"><TABLE CELLSPACING=0 BORDER=0 CELLPADDING=7 WIDTH=528>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-h</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a remote hostname or IP address on which the mSQL server is running. The default is to connect to a server on the localhost using a UNIX domain socket rather than TCP/IP (which gives better performance).</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-f</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Specify a non-default configuration file to be loaded. The default action is to load the standard configuration file located in INST_DIR/msql.conf (usually /usr/local/Hughes/msql.conf). Please see the msqlLoadConfigFile entry in the API section of this manual to understand the method used to select the config file from the specified file name.</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-v</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Verbose mode.</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-s</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Use the character Char as the separation character. The default is a comma. </FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-q</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Remove quotes around field values if they exist (the specified character is the quote character).</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">-e</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Use the specified Char as the escape character. The default is \</FONT></TD>
</TR>
</TABLE>
</P>
<DIR>
<DIR>
<DIR>

<B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Description</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlimport loads a flat ASCII data file into an mSQL database table. The file can be formatted using any character as the column separator. When passed through msqlimport, each line of the text file will be loaded as a row in the database table. The separation character, as specified by the -s flag, will be used to split the line of text into columns. If the data uses a specific character to escape any occurrence of the separation character in the data, the escape character can be specified with the -e flag and will be removed from the data before it is inserted.  Some data formats (such as the CSV format) will enclose an entire value in quotation marks.  The q option can be used to indicate such a format and to specify the character being used for quoting.</P>
<P ALIGN="JUSTIFY">To import a file formatted in the Comma Separated Values format (CSV) into a table called staff in the company database, the msqlimport command below would be used.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>msqlimport  s ,  -q &quot;  e &quot;  company staff</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767755">Lite : mSQLs Scripting Language</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The fact that mSQL can be accessed from virtually every popular scripting language used on UNIX systems has been one of the factors of its popularity. To overcome the often time-consuming process of adding mSQL support to an existing language, such as Perl or Tcl, mSQL 2.0 includes its own scripting language preconfigured with support for the mSQL API.  The scripting language, called Lite, is the same language used by W3-mSQL, the WWW to mSQL interface package. People wishing to access mSQL from stand-alone scripts or via the web now have to learn only one simple yet powerful language. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767756">Basics</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Lite has been designed to mimic the syntax and semantics of the C language while reducing some of the complexities and error prone features of C.  This is intentional as most programmers working on UNIX machines have a working knowledge of C but look for a more "easy to use" language for scripting. The main changes from C are </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
<P ALIGN="JUSTIFY"><LI>All memory management (i.e. allocation and deallocation of memory for variables) is taken care of by the Lite Virtual Machine. Your script does not need to perform any memory management operations. </LI></P>
<P ALIGN="JUSTIFY"><LI>A variable has no fixed type. It will contain whatever is stored in it (e.g char value, numeric value). When you perform an operation on a variable, such as maths or comparisons, the contents of the variable are checked to ensure they are of the correct type. This concept will become clearer as we progress through this documentation. </LI></P>
<P ALIGN="JUSTIFY"><LI>There is a dynamic array type. Each element of the array is a variable as described above. The elements are accessed as they are in C, i.e. variable[offset], but they need not be declared before use. That is, the array element is created when a value is stored in it without a pre-definition of the array. </LI></P>
<P ALIGN="JUSTIFY"><LI>Variables are not pre-declared. They are created when they are first used. </LI></P>
<P ALIGN="JUSTIFY"><LI>Variable names must start with a $ character. This will be familiar to shell script programmers. </LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767757">Variables, Types and Expressions</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Variables are constructed from a $ sign followed by alpha-numeric characters and the '_' character. The only restriction placed upon the name of a variable is that the first character of a user defined variable must not be an upper case character. There is no need to pre-declare variables as you do in a language such as C. A variable is created the first time you assign a value to it. Similarly, the type of the variable is defined by the value that you assign to it. There are four types of scalar variables </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
<P ALIGN="JUSTIFY"><LI>char</LI></P>
<P ALIGN="JUSTIFY"><LI>integer</LI></P>
<P ALIGN="JUSTIFY"><LI>unsigned integers </LI></P>
<P ALIGN="JUSTIFY"><LI>real number </LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">The example code below illustrates the creation of variables </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$int_value = 9;</P>
<P>$uint_value = (uint)240983;$char_value = "Some text value";$real_value = 12.627;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">At any point in time, the type of a value can be changed by using the type cast notation from the C language. If, for example, you wished to include a numeric value from an integer variable in a text string, you would simply cast the integer value to the char type. The code below would result in a char variable that contained the string "1234" .</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>$int_val = 1234;$char_val = (char) $int_val;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The valid type casts are listed below (note uint casts are valid wherever an int cast would be) </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=438>
<TR><TD WIDTH="11%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">From</B></FONT></TD>
<TD WIDTH="11%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">To</B></FONT></TD>
<TD WIDTH="52%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Result</B></FONT></TD>
<TD WIDTH="26%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Example</B></FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">int</FONT></TD>
<TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">char</FONT></TD>
<TD WIDTH="52%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Text representation of numeric string</FONT></TD>
<TD WIDTH="26%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">12 = "12"</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">int</FONT></TD>
<TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">real</FONT></TD>
<TD WIDTH="52%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Real representation of integer value</FONT></TD>
<TD WIDTH="26%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">12 = 12.0</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">real</FONT></TD>
<TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">char</FONT></TD>
<TD WIDTH="52%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Text representation of real value</FONT></TD>
<TD WIDTH="26%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">123.45 = "123.45"</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">real</FONT></TD>
<TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">int</FONT></TD>
<TD WIDTH="52%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Integer representation of real value</FONT></TD>
<TD WIDTH="26%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">123.45 = 123</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Array variables are supported by Lite but there is no fixed type for the array. Each element of the array can hold data from any of the available data types. An array is created by assigning a value to one of the array elements such as </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>$arrayval[3] = "Foo";$arrayval[4] = 5;$arrayval[6] = 1.23 + 5.38;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Lite expressions are formed from mathematical equations incorporating the values of variables and values returned from function calls. Lite is a little more flexible than other languages such as C. It will allow you to do maths operations on all data types including the char type. Adding two char values together results in the concatenation of the two strings. You can also perform maths on values of different types by casting the value to the correct type within the expression. Examples are given below.</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>$charval = "Hello" + " there!";$intval = 8 + 1;$charval = (char)$intval + " green bottles";</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The first expression would result in the char value "Hello there!". The second would result in the integer value 9. The final expression would result in the char value "9 green bottles" using the text representation of the value of $intval from the previous line. Maths expression of any complexity, including any number of sub expressions enclosed in ( ) characters, are supported. </P>
<P ALIGN="JUSTIFY">The table below lists the available maths operators and the data types to which they may be applied. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=438>
<TR><TD WIDTH="23%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Operator</B></FONT></TD>
<TD WIDTH="22%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
<TD WIDTH="18%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Int</B></FONT></TD>
<TD WIDTH="18%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Text</B></FONT></TD>
<TD WIDTH="19%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Real</B></FONT></TD>
</TR>
<TR><TD WIDTH="23%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">+</FONT></TD>
<TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Addition</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
<TD WIDTH="19%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
</TR>
<TR><TD WIDTH="23%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">-</FONT></TD>
<TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Subtraction</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">No</FONT></TD>
<TD WIDTH="19%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
</TR>
<TR><TD WIDTH="23%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">/</FONT></TD>
<TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Division</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">No</FONT></TD>
<TD WIDTH="19%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
</TR>
<TR><TD WIDTH="23%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">*</FONT></TD>
<TD WIDTH="22%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Multiplication</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
<TD WIDTH="18%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">No</FONT></TD>
<TD WIDTH="19%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">Yes</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">A special operator supported by Lite is the count operator written as the # sign. The count operator is used to determine the size of certain variables. If you apply the count operator to a char value it will evaluate to the number of characters in the string. If you apply it to an array it will evaluate to the number of elements in that array. In the first example below, $intval would contain the value 5. In the second example, it would contain 3. </P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$charval = "Hello";$intval = # $charval;$array[0] = 0;$array[1] = 1;$array[2] = 2;$intval = # $array;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767758">Conditions and Loops</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Conditions are provided by Lite using the same syntax as C. That is, the conditional block is started by an 'if (condition)'. The blocks of code are defined using the { and } character. Unlike C, you must always wrap code blocks in { } characters (in C you don't have to if the code block is only one line long). After the initial code block, an optional 'else' block may be defined. </P>
<P ALIGN="JUSTIFY">Multiple parts of the conditional expression may be linked together using logical ANDs and ORs. Like C, the syntax for an AND is &amp;&amp; while the syntax for an OR is ||. As you will see in the example below, Lite provides more flexibility than C in conditions containing text values. You can compare two text values using the '==' equality test or the '!=' inequality test rather than having to use a function such as strcmp(). </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>if ($intval 5 &amp;&amp; $intval &lt; 10){</P>
<P>echo("The value is between 5 and 10\n"); </P>
<P>}else{</P>
<P>echo("The value is not between 5 and 10\n"); </P>
<P>}if ($charval == ""){</P>
<P>echo("The variable contains no value!!!\n"); </P>
<P>} </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Lite supports only one form of looping - a 'while' loop. The syntax and operation of the while loop is identical to the while loop offered by the C language. This includes the use of 'continue' and 'break' clauses to control the flow of execution within the loop. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>while ($intval &lt; 10){</P>
<P>$intval = $intval + 1; </P>
<P>}while ($charval != ""){</P>
<P>$charval = readln($fd); </P>
<P>if ($charval == "Hello")</P>
<P>{</P><DIR>
<DIR>

<P>break; </P></DIR>
</DIR>

<P>}</P>
<P> } </P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767759">User Defined Functions</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">As with most modern programming languages, Lite allows you to write user defined functions. The definition of a Lite function is </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>funct functName ( type arg, type arg ...)</P>
<P>{</P>
<P>statements</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">As the definition dictates, a function must be started with the <I>funct</I> label. The remainder looks like a C function declaration in that there is a function name followed by a list of typed arguments. Any type may be passed to a function and any type may be returned from a function. All values passed to a function are passed by value not by reference. A few example functions are given below. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>funct addition ( int $value1, int $value2 )</P>
<P>{</P>
<P>$result = $value1 + $value2;</P>
<P>return ( $value );</P>
<P>}</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>funct merge ( array $values, int $numVals)</P>
<P>{</P>
<P>$count = 0;</P>
<P>$result = "";</P>
<P>while ( $count &lt; $numValues)</P>
<P>&#9;{</P><DIR>
<DIR>

<P>$result = $result + $values [ $count ];</P>
<P>$count = $count + 1;</P></DIR>
</DIR>

<P>&#9;}</P>
<P>return ( $result );</P>
<P>}</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>funct sequence ( int $first, int $last )</P>
<P>{</P>
<P>$count = 0;</P>
<P>while ( $first &lt; $last )</P>
<P>&#9;{</P><DIR>
<DIR>

<P>$array [$count] = (char) $first;</P>
<P>$first = $first + 1;</P></DIR>
</DIR>

<P>&#9;}</P>
<P>return ( $array );</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">It must be noted that function declarations can only be made before any of the actual script code of the file. That is, all functions must be defined before the main body of the script is reached. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Lite enforces a strict scope on variables used in user defined functions.  Any variable referenced by the function is defined as a local variable in that function even if there is a global variable by the same name.  Parameters are passed by value, not by reference, so any modification of the parameter variables is not reflected outside the scope of the function.  The only way to modify the value of variables outside the scope of the function is by returning a value from the function or by explicitly referencing global variables as outlined below.</P>
<P ALIGN="JUSTIFY">Lite supports the concept of explicitly accessible global variable by using a different syntax when referencing the variable.  If a variable is referenced as $variable then it is a variable within the current scope (a local variable if it is referenced in a function, a global variable if referenced from the main code).  If a variable is to be explicitly referenced as a global variable then it can be referenced as @variable rather than $variable  (a preceeding &quot;@&quot; character rather than a &quot;$&quot; character).  This will force the Lite symbol table management routines to access the global symbol table rather than the symbol table associated with the current execution scope.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767760">User Defined Libraries</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To help provide an efficient programming environment, Lite (and W3-mSQL) allows you to build a library of functions and load the library into your script at run-time. This allows for effective re-use of code in the same way the languages such as C allow you to re-use code by linking against libraries. The main difference is that the library is not "linked" into the script, it is loaded on request at run-time (a little like a C shared library). If the functions that were defined in the previous section of this manual were placed into a library called "mylib", a script could access those functions by loading the library as depicted below. </P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>load "mylib.lib";</P>
<P>&nbsp;</P>
<P>/*</P>
<P>** Now we can use the functions from the &quot;mylib&quot; library</P>
<P>*/</P>
<P>$array = sequence(1,10);</P>
<P>$count = 0;</P>
<P>while ($count &lt; # $array)</P>
<P>{</P>
<P>printf("Value %d is '%s'\n", $count, $array);</P>
<P>$count = $count + 1;</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The power and convenience of Lite libraries is most obvious when writing large WWW based applications using W3-mSQL. Like any application, there will be actions that you will need to perform several times. Without the aid of libraries, the code to perform those actions would need to be re-coded into each W3-mSQL enhanced web page (because each HTML file is a stand-alone program). By placing all these commonly used functions into a library, each web page can simply load the library and have access to the functions. This also provides a single place at which modifications can be made that are reflected in all web pages that load the library. </P>
<P ALIGN="JUSTIFY">Library files are not like normal Lite script files. A Lite script file is a plain ASCII text file that is parsed at run-time by Lite. A library file contains pre-compiled versions of the Lite functions that will load faster as they do not need to be re-parsed every time they are used. A Lite library file is created by using the -l flag of the Lite interpreter. If a set of functions was placed in a file called mylib.lite, a compiled version of the library would be created using the syntax shown below. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>lite -lmylib.lib mylib.lite</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">The -l flag tells Lite to compile the functions and write the binary version of the functions to a file called mylib.lib. This is similar to the concept of using the C compiler to create an object file by using the -c flag of the compiler. </P>
<P ALIGN="JUSTIFY">There are three points that should be noted about the use of Lite libraries. Firstly, it should be noted that a Lite library can only contain functions (i.e. it cannot contain any "main body" code that you would normally include in a script file). Secondly, like functions themselves, a library can only be loaded into a Lite script prior to the start of the main body code. Finally, the path given to the load command within the script does not enforce a known location for the library file. If you specify the library file as "mylib.lib" then Lite will expect the library file to exist in the current directory. You can of course provide a complete pathname rather than just a filename to the load command. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767761">Lite's Standard Module</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The standard module is to Lite as the standard C library is to C. It is a library of functions that are available to all Lite programs. It provides basic functionality for string manipulation, file IO and other normal expectations of a programming language. Outlined below is a description of each of the functions available within the standard module. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767762">Input Output Routines</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">echo ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>echo ( string )</P>
<P>char * string </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">echo() outputs the content of string to the standard output of the Lite script (or as text to be included in the generated HTML of a W3-mSQL page). Any variables that are included in string are evaluated and expanded before the output is generated. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>$name = "Bambi";</P>
<P>echo("My name is $name\n");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">printf ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>printf ( format [ , arg ... ] ) </P>
<P>char * format </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">printf() produces output in a manner similar to the echo function (i.e. sent to the standard output or included in the generated HTML). The semantics of the function are the same as those of printf() in C. The printf() format can include field width and justification information. Specification of a format field as "%17s" will generate a right justified value 17 characters wide. Prefixing the field width definition with the '-' character will produce a left justified result. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>It should be noted that unlike echo(), any variables included in the format string passed to printf() are not expanded before the output is generated. The only way to include variable values in the output is to use C styled format definitions (such as "%s" for a string value etc). </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$name = "Bambi";</P>
<P>printf("My name is also %s\n", $name);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">fprintf ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>fprintf ( fd , format [ , arg ... ] ) </P>
<P>int fd</P>
<P>char * format </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Like printf(), fprintf() produces text output based on the content of the format string and the arguments passed to the function. Unlike printf(), fprintf() sends the output to a file rather than including it in the HTML sent to the browser. The first argument is a file descriptor as returned by the open() function. See the description of open() below for more information. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$name = "Bambi";</P>
<P>$fd = open("/tmp/name","");</P>
<P>fprintf($fd, "My name is $name\n");</P>
<P>close($fd);</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">open ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int fd = open ( path , access )</P>
<P>char * path</P>
<P>char * access</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">open() opens the object (usually a file) pointed to by path for reading and/or writing as specified by the access argument, and returns a file descriptor for that newly opened file. The possible values for the access flags are: </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="16%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Flag</B></FONT></TD>
<TD WIDTH="84%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&lt;</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">File is opened for reading</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&gt;</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">File is opened for writing</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&lt;&gt;</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">File is opened for reading and writing</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&lt;P</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Create a named pipe in the file system and open it for reading</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&gt;P</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Create a named pipe in the file system and open it for writing</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&lt;|</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The contents of the path argument is a shell command.  The command is executed and the output of the new process is available to be read from the returned file descriptor </FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">&gt;|</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The contents of the path argument is a shell command.  The command is executed and any data written to the returned file descriptor is passed as input to the new process</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">An error is indicated by a returned value of 1.  In such a case, the system variable $ERRMSG will contain the error message.</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>It should be noted that both the named pipe related modes create the pipe prior to accessing it.  If the pipe exists in the file system prior to the call, open() will fail.</P>
<P ALIGN="JUSTIFY">Example :</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$fd  = open(&quot;/tmp/output&quot;, &quot;&gt;&quot;);</P>
<P>if ($fd &lt; 0) {</P>
<P>echo(&quot;Error : $ERRMSG\n&quot;);</P>
<P>} else {</P>
<P>fprintf($fd,&quot;This is a test\n&quot;);</P>
<P>close($fd);</P>
<P>}</P>
<P>&nbsp;</P>
<P>&nbsp;</P>
<P>$fd = open("ls -l /etc", "&lt;|");</P>
<P>$line = readln($fd);</P>
<P>printf($line);</P>
<P>close($fd);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">close ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>close ( fd ) </P>
<P>int fd</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">close() closes an open file descriptor.  If the descriptor relates to a file or a pipe, the file or pipe is closed.  If the descriptor is a process, the stdin of the process is closed (and the process should terminate when it reads an EOF from its input).</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Please note that if you do not close all file descriptors you open then you will eventually run out of file descriptors.</P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$fd = open("/tmp/input", "&lt;");</P>
<P>close ($fd);</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">read ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>read ( fd , numBytes )</P>
<P>int fd</P>
<P>int numBytes</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">read() reads numBytes bytes of data from the specified file descriptor and returns the data. It returns the empty string "" when on end of file or error. $ERRMSG will be set if an error occurred. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$fd = open("/etc/passwd","&lt;");</P>
<P>$buf = read($fd, 80);</P>
<P>if ($buf == "")</P>
<P>{</P>
<P>if ($ERRMSG != "")</P>
<P>&#9;{</P><DIR>
<DIR>

<P>printf("Read Error : $ERRMSG\n");</P></DIR>
</DIR>

<P>&#9;}</P>
<P>else</P>
<P>&#9;{</P><DIR>
<DIR>

<P>printf("Read : End Of File\n");</P></DIR>
</DIR>

<P>&#9;}</P>
<P>}</P>
<P>else</P>
<P>{</P>
<P>printf("$buf\n");</P>
<P>}</P>
<P>close($fd);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">readln ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>readln ( fd )</P>
<P>int fd</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">readln() reads a line of text from the nominated file descriptor and returns the data. The newline value is not removed from the data returned. Like read(), the return of an empty string indicates EOF or an error. $ERRMSG will be set to a non-empty string on error. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$fd = open("/etc/passwd","&lt;");</P>
<P>$line = readln($fd);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">readtok ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>readtok ( fd , token )</P>
<P>int fd</P>
<P>char * token </P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">readtok() reads data from the file descriptor until it finds the character specified as the token in the input data. Only the data read prior to the token is returned, the token character itself is not. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>Please note that the token is a single character value. If more than one character is passed in the token argument, only the first character is used. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$fd = open("/etc/passwd", "&lt;");</P>
<P>$username = readtok($fd, ":");</P>
<P>printf("Username is '$username'\n");</P>
<P>close($fd);</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767763">String Manipulation Routines</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">split ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>split ( str , token )</P>
<P>char * str ,  * token </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">split() splits the contents of a variable into multiple substrings using the value of token as the separator character. The result of splitting the string is returned as an array. If more than one character is passed as the token, all but the first character is ignored. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$line = "bambi:David Hughes:Hughes Technologies";</P>
<P>$info = split($line,":");</P>
<P>printf("Username = $info[0]\n");</P>
<P>printf("Full name = $info[1]\n");</P>
<P>printf("Organisation = $info[2]\n");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">strseg ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>strseg ( str , start, end )</P>
<P>char * str</P>
<P>int start , end</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">strseg() returns a segment of the string passed as the str argument. The segment starts at start characters from the start of the string and ends at end characters from the start of the string. In the example below, $sub will contain the string "is a". </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$string = "This is a test";</P>
<P>$sub = strseg($string, 5, 8,);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">chop ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * chop ( str ) </P>
<P>char * str </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">chop() removes the last character from the text string str and returns the new value. The primary use of this function is for chopping end-of-line characters off strings read from files with readln(). </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$line = readln($fd);</P>
<P>$line = chop($line);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">tr ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * tr ( str , expr1 , expr2 )</P>
<P>char * str ,  * expr1 ,  * expr2 </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">tr() performs text translations on the string argument str based on the contents of expr1 and expr2 and returns the modified string value. expr1 and expr2 are sets of characters. Any character that is found in str that matches a character in expr1 is translated to the corresponding character from expr2. The character sets can be defined by listing individual characters or by providing character ranges ( such as A-Z to indicate all characters between A and Z ). The example below will translate any upper case characters to lower case and translate any exclamation marks '!' found in the string with a full stop '.' </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$str = "Hello There!";</P>
<P>$str = tr($str, "A-Z!", "a-z.");</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">sub ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * sub ( str , expr1 , expr2 )</P>
<P>char * str ,  * expr1 ,  * expr2 </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">sub() performs string substitutions on the string argument str based on the contents of expr1 and expr2. If the string value passed as expr1 is found anywhere in str it is substituted for the value if expr2. The example below would leave the value "This was a test" in $str. Note that unlike tr() the length of the string can be modified bt sub() as there is no restriction on the content or length of the value of expr2. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$str = "This is a test";</P>
<P>$str = sub($str, "is", "was");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">substr ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>char * substr ( str , regexp , pattern )</P>
<P>char * str ,  * regexp , * pattern</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">substr() extracts substrings from str based on the regular expression regexp and the extraction pattern patter. Any parts of the string that are matched by parts of the regular expression enclosed in parenthesis are made available to the extraction pattern. The first such substring is available as $1, the second as $2 and so on. The string value created by expanding any such variables in pattern is returned. The example below would produce the string "Who's Jack?" as the regular expression enclosed in parenthesis will match a word containing a leading capital letter followed by lower case letter. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$str = "well, Jack is alright.";</P>
<P>$new = substr($str, ".* ([A-Z][a-z]*) .*", </P>
<P>"Who's $1?");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767764">File Manipulation Routines</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">test ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>test ( test, filename ) </P>
<P>char * test</P>
<P>char * filename </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">test() offers functionality similar to the test program provided by the shell. Given a filename and a test, it will determine if the file matches the test specification. If it matches, 1 is returned otherwise 0 is returned.   A table outlining the available tests is shown below.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="16%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Test</B></FONT></TD>
<TD WIDTH="84%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">File Type</B></FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"b"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">Block mode device</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"c"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">Character mode device</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"d"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">Directory</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"p"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">Named pipe</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"s"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">Non-empty regular file</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"f"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">Regular file</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"u"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">File is setuid</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">"g"</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP"><DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY">File is setgid</DIR>
</DIR>
</DIR>
</FONT></TD>
</TR>
</TABLE>
</P>
<DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY"> </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (test("b", "/tmp/foo") == 1)</P>
<P>{</P>
<P>echo("/tmp/foo is a block device\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">unlink ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>unlink ( path ) </P>
<P>char * path </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">unlink() removes the named file from the file system. If the file does not exist or another error occurs, a negative value is returned and the $ERRMSG variable is set to an appropriate error message</P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (unlink("/tmp/foo") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">umask ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>umask ( mask ) </P>
<P>int mask </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">umask() sets the umask for the current process (see the system manual page for a description of a umask). As with any numeric value, the mask can be given in decimal, hex or octal. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>umask(0227);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">chmod ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>chmod ( path , mode) </P>
<P>char * path</P>
<P>int mode </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">chmod() changes the mode of the specified file to the specified mode. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (chmod("/tmp/foo", 0700) &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">mkdir ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>mkdir ( path ) </P>
<P>char * path </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">mkdir() creates the directory specified by path. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (mkdir("/tmp/myDirectory") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">chdir ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>chdir ( path ) </P>
<P>char * path </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">chdir() changes directory to the specified path. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (chdir("/tmp/myDirectory") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
<P>&nbsp;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">rmdir ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>rmdir ( path ) </P>
<P>char * path </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">rmdir() removes the specified director from the file system. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (rmdir("/tmp/myDirectory") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">rename ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>rename ( old , new ) </P>
<P>char * old</P>
<P>char * new </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">rename() renames the specified file from the old name to the new name. You cannot rename files over the boundary of a file system. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (rename("/tmp/foo", "/tmp/baa") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">truncate ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>truncate ( path , length) </P>
<P>char * path</P>
<P>int length </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">truncate() will set the length of the file to the specified length. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (truncate("/tmp/foo", 0) &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">link ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>link ( path , new ) </P>
<P>char * path</P>
<P>char * new </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">link() will create a new link named new to the file specified by path. You cannot create a link over a file system boundary. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (link("/tmp/foo", "/tmp/baa") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">symlink ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>symlink ( path , new) </P>
<P>char * path</P>
<P>char * new </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">symlink() will create a symbolic link called new to the file specified by path. </P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>It should be noted that if the installation process determined that your operating system does not support the symlink() system call this function will not be available. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (symlink("/tmp/foo", "/tmp/baa") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">stat ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>stat ( path ) </P>
<P>char * path </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">stat() provides an interface to the stat() system call. The information from stat() is returned as an array. The elements of the array are: </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=570>
<TR><TD WIDTH="12%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Field</B></FONT></TD>
<TD WIDTH="88%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">0</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Inode number</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">1</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">File mode</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">2</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Number of links to file</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">3</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">UID</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">4</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">GID</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">5</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Size of file</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">6</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">atime</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">7</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">mtime</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">8</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">ctime</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">9</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Block size of file system</FONT></TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">10</FONT></TD>
<TD WIDTH="88%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Number of file system blocks used</FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$sbuf = stat("/tmp/foo");</P>
<P>if ( #$sbuf == 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
<P>else</P>
<P>{</P>
<P>echo("/tmp/foo is $sbuf[5] bytes long\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767765">Process Oriented Routines</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Note : System facilities such as fork and exec are not available in the standard module. As this module is shared by both Lite and W3-mSQL it is not appropriate for such calls to be included here (having web pages fork child processes is not a sound idea). A supplementary module called mod_proc will be made available to provide these facilities. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">sleep ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>sleep ( time ) </P>
<P>int time </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">sleep() will suspend operation of the script for time seconds. </P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">&nbsp;</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">system ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>system ( command ) </P>
<P>char * command </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">system() will execute the command line specified by command in a subshell. Any output generated by the command is included in the HTML output. The exit status of the command is returned to the caller. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (system("ls -l") != 0)</P>
<P>{</P>
<P>echo("Error running ls! \n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">getpid ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>getpid ( ) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">getpid() returns the process ID of the process running Lite.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">getppid ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>getppid ( ) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">getppid() returns the process ID of the process that is the parent of the process running Lite. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">kill ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>kill ( pid , signal ) </P>
<P>int pid</P>
<P>int signal </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">kill() sends the specified signal to the specified process. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (kill(1, 9) &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767766">Date / Time Related Routines</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">time ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>time ( ) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">time() returns the time since 00:00:00 GMT, Jan. 1, 1970, measured in seconds as an integer value. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$time = time();</P>
<P>echo("The number of seconds since Jan 1 1970 is $time\n");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">ctime ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>ctime ( time ) </P>
<P>int time </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">ctime() converts a value returned by time() into the standard UNIX text representation of the date and time. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$time = time();</P>
<P>printf("The date and time is '%s'\n", </P>
<P>ctime($time));</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">time2unixtime ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>time2unixtime ( sec, min, hour, day, month, year )</P>
<P>int sec , min , hour , day ,  month ,  year;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">time2unixtime() provides a facility by which you can create a standard UNIX time value (i.e. the time since 00:00:00 GMT, Jan. 1, 1970, measured in seconds) for any specified date/time. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$time = time();</P>
<P>$time2000 = time2unixtime(0,0,0,1,1,2000);</P>
<P>printf("The number of seconds before the end of the century is %d\n",</P>
<P>$time2000 - $time);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">unixtime2* ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>unixtime2* ( time ) </P>
<P>int time; </P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The above functions take a UNIX time value (i.e. seconds since Jan 1, 1970) and return an integer value representing part of the time information.   A list of the functionality provided by the individual routines is shown below.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
<P ALIGN="JUSTIFY"><LI>unixtime2year() - The year in which time falls </LI></P>
<P ALIGN="JUSTIFY"><LI>unixtime2month() - 1 to 12 representing the month in which time falls</LI></P>
<P ALIGN="JUSTIFY"><LI>unixtime2day() - 1 to 31 representing the day in which time falls </LI></P>
<P ALIGN="JUSTIFY"><LI>unixtime2hour() - 0 to 23 representing the month in which time falls </LI></P>
<P ALIGN="JUSTIFY"><LI>unixtime2min() - 0 to 59 representing the minute in which time falls </LI></P>
<P ALIGN="JUSTIFY"><LI>unixtime2sec() - 0 to 59 representing the second from the start of the minute in which time falls </LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Example : </P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$time = time();</P>
<P>$year = unixtime2year($time);</P>
<P>$month = unixtime2month($time);</P>
<P>$day = unixtime2day($time);</P>
<P>&nbsp;</P>
<P>echo("The date is $day/$month/$year\n");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">strftime ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>time ( fmt, time ) </P>
<P>char * fmt; int time; </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">strftime( ) returns a text representation of the UNIX time value time based on the format string passed as fmt. The available formatting options are </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="15%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Option</B></FONT></TD>
<TD WIDTH="85%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%a</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">day of week, using locale's abbreviated weekday names</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%A</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">day of week, using locale's full weekday names</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%b</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">month, using locale's abbreviated month names</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%B</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">month, using locale's full month names</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%d</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">day of month (01-31)</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%D</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">date as %m/%d/%y</FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%e</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Day of month (1-31 with single digits preceded by a space) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%H</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">hour (00-23) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%I</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">hour (00-12) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%j</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Day of year (001-366) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%k</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">hour (0-23, blank padded) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%l</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">hour (1-12, blank padded) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%m</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">month number (01-12) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%M</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">minute (00-59) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%p</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">AM or PM </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%S</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">seconds (00-59) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%T</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">time as %H:%M:%S </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%U</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">week number in year (01-52) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%w</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">day of week (0-6, Sunday being 0) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%y</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">year within the century (00-99) </FONT></TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">%Y</FONT></TD>
<TD WIDTH="85%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">year including century (e.g. 1999) </FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$time = time();</P>
<P>$message = strftime("The time is %H:%M:%S on %A, %e %B", $time);</P>
<P>echo("$message\n");</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767767">Password file Related Routines</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">getpwnam ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>getpwnam ( uname ) </P>
<P>char * uname </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Returns the passwd file entry for the user specified by uname. The result is returned as an array with the array elements defined as below. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=594>
<TR><TD WIDTH="11%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Element</B></FONT></TD>
<TD WIDTH="89%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Contents</B></FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">0</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">username</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">1</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">password</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">2</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">UID</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">3</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">GID</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">4</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">GECOS</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">5</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">home directory</FONT></TD>
</TR>
<TR><TD WIDTH="11%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">6</FONT></TD>
<TD WIDTH="89%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">shell</FONT></TD>
</TR>
</TABLE>
</P>

<B><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>

<P ALIGN="JUSTIFY">Example : </P>
</B><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$pwinfo = getpwnam("bambi");</P>
<P>if ( # $pwinfo == 0)</P>
<P>{</P>
<P>echo("User 'bambi' does not exist!\n");</P>
<P>exit(1);</P>
<P>}</P>
<P>printf("Bambi's home directory is %s and his uid is %d\n",</P>
<P>$pwinfo[5], (int)$pwinfo[2]);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">getpwuid ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>getpwuid ( UID ) </P>
<P>int UID </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">getpwuid() returns the same information as getpwnam() but uses a UID to identify the user rather than a username. See the definition of getpwnam() above for details of the return format and usage. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767768">Network Related Routines</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">gethostbyname ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>gethostbyname ( host ) </P>
<P>char * host </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">gethostbyname() returns an array of information about the specified host. Element 0 of the array contains the hostname while element 1 contains the hosts IP address. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$info = gethostbyname("www.Hughes.com.au");</P>
<P>if ( # $info == 0)</P>
<P>{</P>
<P>echo("Host unknown!\n");</P>
<P>}</P>
<P>else</P>
<P>{</P>
<P>echo("IP Address = $info[1]\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">gethostbyaddress ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>gethostbyaddress ( addr ) </P>
<P>char * addr </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">gethostbyaddr() returns an array of information about the specified host. Element 0 of the array contains the hostname while element 1 contains the hosts IP address. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$info = gethostbyaddr("127.0.0.1");</P>
<P>if ( # $info == 0)</P>
<P>{</P>
<P>echo("Host unknown!\n");</P>
<P>}</P>
<P>else</P>
<P>{</P>
<P>echo("Host name = $info[0]\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767769">Routines available only in W3-mSQL</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">urlEncode ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>urlEncode ( str ) </P>
<P>char str </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">urlEncode() returns a URL encoded version of the specified string. The returned data can then be used in GET method operations without any potential problems of not conforming to the data encoding standard. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$value = urlEncode("This's a test");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">setContentType ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>setContentType ( str ) </P>
<P>char *str </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">setContentType() can be used to override the default content type sent to in the HTML header of the generated HTML output. If it is to be used, it must be the first line of the script. Note : not even a blank line may preceed a call to setContentType(). </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>setContentType("image/gif");</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">includeFile ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>includeFile ( filename ) </P>
<P>char *filename </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">includeFile() may be used to include the contents of the specified file in the HTML output sent to the browser. The contents of the file are not modified or parsed in any way. If the first character of the file name is a / then the filename is an absolute path name from the root directory of the machine. If it is note, the filename is a relative path from the location of the script file. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>includeFile("standard_footer.html");</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767770">Lite's mSQL Module</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The Mini SQL module is a library of routines for communicating with a Mini SQL database. The functions provided by this module mimic the functions provided by the mSQL C API. Please see the mSQL documentation for more information. </P>
<P ALIGN="JUSTIFY">Outlined below is a description of each of the functions available within the Mini SQL module. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlConnect ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlConnect ( host ) </P>
<P>char *host </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlConnect() connects to the mSQL server on the specified host. If no host is specified it connects to the local mSQL server. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$sock = msqlConnect("research.Hughes.com.au");</P>
<P>if ($sock &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlClose ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlConnect ( sock ) </P>
<P>int sock </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlClose() closes a connection made using msqlConnect(). </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlClose($sock);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlSelectDB ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlSelectDB ( sock , db ) </P>
<P>int sock</P>
<P>char *db </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlSelectDB() tells the mSQL server which database you wish to use. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (msqlSelectDB($sock,"my_db") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">msqlQuery ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlQuery ( sock , query ) </P>
<P>int sock</P>
<P>char *query </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlQuery() submits a query to the mSQL server connected to the specified socket. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>if (msqlQuery($sock, "select * from foo") &lt; 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlStoreResult ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlStoreResult ( ) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlStoreResult() stores any data that was a result of the previous query. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$res = msqlStoreResult();</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFreeResult ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlFreeResult ( res ) </P>
<P>int res </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlFreeResult() frees any memory allocated to the specified result. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlFreeResult($res);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFetchRow ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlFetchRow ( res ) </P>
<P>int res; </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlFetchRow() returns a single row of the data stored in the specified result. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$row = msqlFetchRow($res);</P>
<P>if ( # $row == 0)</P>
<P>{</P>
<P>echo("ERROR : $ERRMSG\n");</P>
<P>}</P>
<P>else</P>
<P>{</P>
<P>echo("Field 0 is $row[0]\n");</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlDataSeek ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlDataSeek ( res , location ) </P>
<P>int res</P>
<P>int location </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlDataSeek() allows you to move the data pointer within the result table. Specifying a location of 0 will rewind the result. The next call to msqlFetchRow() will return the first row of the result table again. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlDataSeek( $res, 0);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListDBs ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlListDBs ( sock ) </P>
<P>int sock </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlListDBs() returns an array of the names of the databases available on the specified server.</P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$dbs = msqlListDBs($sock);</P>
<P>$index = 0;</P>
<P>while ($index &lt; # $dbs)</P>
<P>{</P>
<P>printf("Database = %s\n", $dbs[$index]);</P>
<P>$index = $index + 1;</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListTables ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlListTables ( sock , db ) </P>
<P>int sock</P>
<P>char *db </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlListTables() returns an array of the names of all the tables available in the current database of the specified server.</P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$tabls = msqlListTables($sock);</P>
<P>$index = 0;</P>
<P>while ($index &lt; # $tabls)</P>
<P>{</P>
<P>printf("Table = %s\n", $tabls[$index]);</P>
<P>$index = $index + 1;</P>
<P>}</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlInitFieldList ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlInitFieldList ( sock , db , table ) </P>
<P>int sock</P>
<P>char *db</P>
<P>char *table </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlInitFieldList() generates an internal result handle containing details of all the fields in the specified table of the specified database. The result handle is used in conjunction with the functions below to access the field structure information. Note that the result handle is held as a static variable inside the mSQL module and further calls to msqlInitFieldList() will free the result. </P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlListField ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlListField ( ) </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlListField() returns an array of information about a single field of the current field list result that was generated using msqlInitFieldList(). The elements of the array contain the following information. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 BORDERCOLOR="#c0c0c0" CELLPADDING=7 WIDTH=576>
<TR><TD WIDTH="24%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Element</B></FONT></TD>
<TD WIDTH="76%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">0</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Field Name</FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">1</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Table Type</FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">2</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Type</FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">3</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Length</FONT></TD>
</TR>
<TR><TD WIDTH="24%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="CENTER">4</FONT></TD>
<TD WIDTH="76%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">Flags</FONT></TD>
</TR>
</TABLE>
</P>
<DIR>
<DIR>
<DIR>

<FONT SIZE=2><P ALIGN="JUSTIFY"> </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$res = msqlInitFieldList($sock,"my_db","my_table");</P>
<P>$field = msqlListField($res);</P>
<P>while( # $res  0)</P>
<P>{</P>
<P>echo("Name $field[0]\n");</P>
<P>$field = msqlListField($res);</P>
<P>}</P>
<P>&nbsp;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlFieldSeek ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlFieldSeek ( res , location ) </P>
<P>int res</P>
<P>int location </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlFieldSeek() acts upon the result of a call to msqlInitFieldList() in the same way msqlDataSeek() acts upon the result of a call to msqlStoreResult(). It allows you to move the internal result pointer to the specified location. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">msqlNumRows ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>int msqlNumRows ( res ) </P>
<P>int res </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlNumRows() returns the number of rows contained in the result handle res. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlQuery($sock, "select * from foo");</P>
<P>$res = msqlStoreResult();</P>
<P>printf("There are %d rows in foo\n",</P>
<P>msqlNumRows($res);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">msqlEncode ( )</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</B></FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>msqlEncode ( string ) </P>
<P>char *string </P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">msqlEncode() is passed a string value that may contain characters that can cause errors in mSQL query strings (such as the ' character in text values). It returns a modified version of the string with all such characters escaped. </P>
<P ALIGN="JUSTIFY">Example : </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>$name = "O'Reilly";</P>
<P>$newName = msqlEscape($name);</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767771">W3-mSQL : The WWW Interface Package</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">W3-mSQL version 2.0 represents the second generation of HTML scripting products developed by Hughes Technologies Pty Ltd. The first generation product provided a simple programatic interface to the mSQL database system from within an HTML document. W3-mSQL 2.0 goes beyond the functionality provided by the first generation W3-mSQL product to enable the development of entire programs within a WWW page while offering comprehensive access control and security features. </P>
<P ALIGN="JUSTIFY">W3-mSQL achieves this by providing a complete programming language embedded within an HTML document. The language, called Lite, is similar is style and syntax to the C programming language and the ESL scripting language. Using W3-mSQL and the embedded Lite language, you can generate HTML code "on-the-fly" in the same way you do when you write custom CGI programs. What's more, you can mix normal HTML code with W3-mSQL code so that you only need to use the CGI styled approach where you actually have to. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767772">Scripting Tags</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To facilitate the W3-mSQL extensions to normal web pages, Lite code is included in your HTML code. It is differentiated from normal HTML code by including it inside &lt;! &gt; tags. As an example, a W3-mSQL version of the legendary Hello World program is provided below. </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>&lt;HTML&gt;</P>
<P>&lt;HEAD&gt;</P>
<P>&lt;TITLE&gt;Hello World from W3-mSQL&lt;/TITLE&gt;</P>
<P>&lt;HEAD&gt;</P>
<P>&lt;BODY&gt;</P>
<P>&lt;CENTER&gt;</P>
<P>&lt;H1&gt;Introduction to W3-mSQL&lt;H1&gt;</P>
<P>&lt;P&gt;</P>
<P>&nbsp;</P>
<P>&lt;! echo("Hello World\n"); &gt;</P>
<P>&lt;\CENTER&gt;</P>
<P>&lt;BODY&gt;</P>
<P>&lt;HTML&gt;</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">As you can see, there is a line of code in the middle of the HTML page, enclosed in &lt;! &gt; tags. When the page is loaded through the W3-mSQL CGI program, anything enclosed in &lt;! &gt; tags is parsed and executed as an embedded program. Any output generated by the program is sent to the user's browser. In this case, the string "Hello World" would be sent as part of the HTML page to the browser. The remainder of the page is sent to the browser unmodified. </P>
<P ALIGN="JUSTIFY">There can be any number of W3-mSQL tags within a single page and there can be any number of lines of code within a single W3-mSQL tag. </P>
<P ALIGN="JUSTIFY">To execute the script depicted in figure do not specify the path to the file in the URL as you would normally do as your browser will just be sent the unprocessed HTML document. To execute the script you must specify a URL that executes the W3-mSQL binary and tells it to load and process your script. The W3-mSQL binary is called w3-msql and will usually be located in the /cgi-bin directory (if it isn't there contact your system administrator). If the normal URL of a W3-mSQL enhaced web page is /staff/lookup.html, you would load it using the following URL: </P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>/cgi-bin/w3-msql/staff/lookup.html</P>
</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY">This URL instructs the web server to execute the W3-mSQL binary and tells it to load the /staff/lookup.html script file.  Some web servers can be configured to execute a CGI based on the suffix of the requested file.  Such a server could be configured to automatically execute the w3-msql CGI program for every file with a suffix of .msql.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767773">Form Data</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">One thing virtually all CGI type programs have in common is that they process the contents of an HTML form. The form data is passed to the CGI program via either a GET or a POST method by the http server. It is then the responsibility of the CGI script to decypher and decode the data being passed to it. W3-mSQL greatly simplifies this process by converting any form data passed to a script into global Lite variables within the Lite Virtual Machine. These variables can then be accessed by your script code. </P>
<P ALIGN="JUSTIFY">When an HTML form is defined, a field name is given to each of the elements of the form. This allows the CGI to determine what the data values being submitted actually mean. When the data is passed to W3-mSQL, the field names are used as the variable names for the global variables. Once a set of variables has been created for each form element, the values being passed to the script are assigned to the variables. This is done automatically during start-up of the W3-mSQL program. </P>
<P ALIGN="JUSTIFY">As an example, imagine that the following form was defined in an HTML page.</P>
<P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&lt;FORM ACTION=/cgi-bin/w3-msql/my_stuff/test.html METHOD=POST&gt;</P>
<P>&lt;INPUT NAME=username SIZE=20&gt;</P>
<P>&lt;INPUT NAME=password SIZE=20 TYPE=PASSWORD&gt;</P>
<P>&lt;SELECT NAME=user_type&gt;</P>
<P>&lt;OPTION VALUE="casual"&gt;Casual User</P>
<P>&lt;OPTION VALUE="staff"&gt;Staff Account</P>
<P>&lt;OPTION VALUE="guest"&gt;Temporary Guest Account</P>
<P>&lt;/SELECT&gt;</P>
<P>&lt;/FORM&gt;</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">In the example we have defined three fields within the form, two text entry fields called username and password, and a menu called user_type. We have also specified that the action for the form is to call W3-mSQL and tell it to process /my_stuff/test.html passing the form data via the POST method. When the data is submitted, the values entered for the three form fields are passed to W3-mSQL. It then creates three global variables called $username, $password and $user_type, and assigns the user's data to those variables. The values can then be accessed within the Lite script code embedded in test.html by referencing the variables. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767774">Security Related Features</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">W3-mSQL tries to address security related issues from several points of view. The most obvious security problem is the management of access to data contained in web pages. A good solution to this problem provides both authentication of the users and access control to restrict access based on where the user is located. W3-mSQL solves this problem with an in-built authorisation scheme known as W3-auth. Because of the importance of W3-auth, we have devoted an entire manual section to it. Please see the W3-auth : Access Control and Authentication section of the manual for a full description of W3-auth and details of its operation and configuration. </P>
<P ALIGN="JUSTIFY">When building "real" applications with a scheme such as W3-mSQL, other security related issues become apparent. Because the actual program code is embedded in the HTML code anyone wishing to obtain a copy of your source code would just need to access the W3-mSQL enhanced web page directly rather than accessing it via the W3-mSQL CGI program. If a user did this, the source code would not be processed and would appear in the HTML sent to the browser. If a user saved the source of the page from their browser they would have a full copy of your source code on their machine. Naturally, this is a major problem for people who write proprietary applications. </P>
<P ALIGN="JUSTIFY">To overcome this problem, W3-mSQL provides two features, private scripts and pre-compiled libraries. Your web server may also provide a feature that can overcome this problem. All three options are discussed below. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">Private Scripts</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A problem associated with embedding your source code in an HTML document is that by pure definition an HTML document is a public document (available to anyone via your web server). The software we write with W3-mSQL is safe as long as the user only accesses it via the W3-mSQL CGI program (because it will be processed and removed from the HTML source before it is sent to the browser). So the problem is not that the source code is in the HTML file, it is that a user may access the HTML file directly by specifying the URL and bypass the W3-mSQL CGI program. </P>
<P ALIGN="JUSTIFY">The obvious solution to this problem would be if the HTML file was not available directly from the web server. If that was the case the user couldn't specify the URL directly and as such could not download your source code. But, how is this possible if the W3-mSQL expects to find the enhanced HTML file in the web document space? The solution is to install your enhanced web pages as private scripts. </P>
<P ALIGN="JUSTIFY">A private script is an HTML file that is installed outside the web document tree (i.e. it is not directly available through your web server). When a page is requested via W3-mSQL, it looks for the file based on the URL specified. For example, if you requested the page /cgi-bin/w3-msql/test/myfile.html, W3-mSQL would try to load and process WEB_ROOT/test/myfile.html where WEB_ROOT is the directory in which you install web pages (such as /usr/local/etc/htdocs or similar). If it finds the file at that location is will load and process it. If it doesn't find the file at that location, W3-mSQL assumes it must be a private script. </P>
<P ALIGN="JUSTIFY">When W3-mSQL determines that the request references a private script (i.e. it didn't find the page in the web tree) it looks in an external directory for the page. The default location for private scripts is /usr/local/Hughes/www. In the example above, W3-mSQL will try to load /usr/local/Hughes/www/test/myfile.html and process it. In short, it will use the private script directory as a second web document tree. You web server does not know that documents are stored in that directory so it is not able to send them without the help of W3-mSQL. </P>
<P ALIGN="JUSTIFY">In the above example, if someone tried to load /test/myfile.html directly, the web server would report an error because the file does not exist in the web tree. If the user then requested it using the W3-mSQL CGI program, a check for the file in the web tree would fail so the file installed in the private script directory would be loaded, processed and sent back to the user. This eliminates the possibility of a user directly accessing your file and downloading your source code. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">Lite Libraries</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Lite libraries are pre-compiled versions of Lite functions that are loaded into Lite scripts and W3-mSQL enhanced web pages at run-time. See the Lite section of this manual for a complete description of Lite libraries.</P>
<P ALIGN="JUSTIFY">From a security point of view, libraries can be used to hide your Lite source code from a user. A library is a binary version of the Lite code in the same way that an object file is a binary version of C code after it has been compiled. If all of your "sensitive" functions are placed in a library then they are totally hidden from the remote users (the binary file will be of no use to anyone as you cannot reverse the process and turn the library back into source code). </P>
<P ALIGN="JUSTIFY">Using libraries in this way also increases the performance of your W3-mSQL applications because the source code does not need to be compiled every time the page is requested (it is compiled once and the binary version is then loaded directly into the Lite Virtual Machine when needed). Please see the section of the Lite documentation covering libraries for further information. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica"><P ALIGN="JUSTIFY">HTTP Server Support</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Some HTTP servers provide a mechanism via which you can map a file extension to a specific action (Apache is an example of such a web server). If your web server provides this feature you can configure it to force the processing of your W3-mSQL enhanced files automatically. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">For example, let us assume that all your enhanced web pages are stored in files with a suffix of .msql (e.g. /test/myfile.msql). You could then configure your web server to process any request for a file ending in .msql through the W3-mSQL CGI program. The web server will ensure that no user can access your enhanced HTML document without it being processed by the W3-mSQL CGI program.  Configuring your web server to do this is specific to the web server you are using. For users of the Apache web server, please see the "Using W3-mSQL with Apache" document in the library section of the Hughes Technologies web site at http://www.Hughes.com.au </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767775">W3-Auth : User authentication for W3-mSQL</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A major problem associated with delivering &quot;real&quot; applications over the World Wide Web is controlling access to the application.  A database application will probably have the facility to modify the data contained in the database as well as simply viewing the information.  Naturally, access to the update facilities must be controlled.  Most web servers provide a username / password facility for controlling access to areas of the document tree.  Configuring such access control usually requires editing files on the server machine itself and running utilities from the UNIX prompt.  Such a scheme is not appropriate for large scale applications or organisations that host a large number of web based applications.</P>
<P ALIGN="JUSTIFY">To overcome these problems, the W3-mSQL package includes an authentication facility.  This facility utilises the HTTP authorisation protocol to determine the users username and password (via the familiar pop-up username box in most web browser packages).  When enabled, W3-mSQL will automatically check the username and password of any user accessing a page that is generated by W3-mSQL.  W3-Auth does not use files on the web server machine nor does it require utilities to be run from the UNIX prompt.  All configuration of W3-Auth based access control is performed via a web interface with the data stored in an mSQL database.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767776">Web Server Requirements</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To determine the username and password of the client, W3-Auth uses the HTTP authorisation protocol.  This protocol will force the browser to prompt the user for a username and password and then return the information to the web server.  The web server software must then make this information available to the W3-mSQL and W3-Auth CGI programs so that the information can be validated.  If the authorisation information is not passed through to the CGI programs, access to the protected pages will never be granted as a username and password can not be validated.</P>
<P ALIGN="JUSTIFY">The usual (and expected) method for passing this information to CGI programs is via a UNIX environment variable.  In general, the web server will create a variable of a pre-defined name containing this information before calling the CGI program.  Unfortunately, some web server developers have viewed the passing of authorisation information as a potential security problem.  The grounding for this view is that a malicious user could install a rogue program on the server and capture peoples passwords.   We do not view this as a problem due to the implied security of a UNIX server.  If a user can overwrite a valid CGI program with a rogue &quot;trojan horse&quot; then the general security of the server machine is not acceptable.  In simple terms, it is similar to saying that keeping a spare set of keys at home is a security risk because if someone breaks into your home they could take a key.  Naturally, if they have already broken into your home they didnt need a key and other areas of your security need to be improved.</P>
<P ALIGN="JUSTIFY">Web servers that are known not to provide this information are those based on the NCSA http server code (most notably the popular Apache web server).  To aid in determining whether or not a server provides this information, we have written a simple test program.  The program is available from the software section of the Hughes Technologies web site (http://www.Hughes.com.au).   To overcome this limitation in the Apache server, we also provide a software patch for Apache on our server.  The patch and a complete distribution of Apache that has already been patched can be found in the software section of our web site.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767777">Terms and Concepts</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">W3-Auth uses several new terms and concepts for managing the access control of your applications.  The definition of these terms and concepts is provided below.</P>
</FONT><FONT SIZE=1><P ALIGN="JUSTIFY">&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><B><FONT SIZE=2><P ALIGN="JUSTIFY">Namespace&#9;</B>A namespace is a logical group of usernames.  If, for example, a company provides web hosting services and wishes to allow clients to use W3-Auth based access control for their application, a namespace could be defined for each client.  If client A has a user called fred and client B also has a user called fred normally they would be viewed as the same person (with the same password).  </P>
<P ALIGN="JUSTIFY">By using multiple namespaces, each client can have a user called fred and they will be viewed as separate people.  It is common to define a namespace for each client or for each W3-mSQL based application on your server (allowing people to have different passwords for different applications).</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<B><P ALIGN="JUSTIFY">Area&#9;</B>An area is a segment of your web document tree that you wish to secure.  An area is defined in terms of the URL used to access the pages. For example, if an application called Trident was developed and installed as &quot;http://your.web.server/trident/&quot; a secure area could be defined covering the /trident section of the web tree.  Any URL that includes /trident as a prefix will be included in the area.</P>
<P ALIGN="JUSTIFY">&#9;Secure areas can be nested to provide greater control.  If, for example, the Trident application contained sections for viewing data and also for editing data, access to the editing features could be restricted using a nested area.  If all the pages associated with editing the database are located in the &quot;/trident/edit&quot; directory, then a second area could be defined to cover /trident/edit.  When a URL is requested, the longest defined prefix that matches the URL indicates the area (i.e. /trident/edit is longer than /trident).</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767778">Configuring W3-Auth</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The first step in configuring W3-Auth is to create the database required for its configuration information.  A Lite script is included in the mSQL distribution to help in this process.  The script is called setup_w3auth and is located in the misc directory.  The script assumes that Lite is located in /usr/local/Hughes/bin.  If you have installed mSQL in a non-default location then you will need to edit the first line of the script to reflect the location of Lite on your machines.</P>
<P ALIGN="JUSTIFY">During the execution of the script several tables will be created in a new database called w3-msql.  It will also setup a &quot;super user&quot; for the initial configuration of the W3-mSQL access control.  You will be prompted for user details of this newly created super user.</P>
<P ALIGN="JUSTIFY">Once the database has been created, the configuration process of W3-Auth can begin.  To start the configuration, simply load the following URL in your web browser</P>
</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>&nbsp;</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

<P>http://your.machine.name/cgi-bin/w3-auth</P>
<P>&nbsp;</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">As the CGI executes you will be prompted for a username and password.  Enter the username and password of the super user you created with the setup_w3auth script.  Once you have logged in you will be prompted to select a namespace in which you will work.  The only available option will be the SuperUser namespace.  This namespace is the &quot;master&quot; namespace in which new namespaces are defined.  A user who has management capabilities in any namespace must be a user of the SuperUser namespace.</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767779">Case Study</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The easiest way to document the configuration process of W3-Auth is by using an example.  In this example, the original SuperUser is a user called bambi.  Using the bambi account we will create a new namespace called Trident and setup a secure area for it.  In our example we will use several users: bambi is the system administrator, bill is the customer who is responsible for maintenance of the new namespace, and fred and john are users of the new namespace.</P>
<P ALIGN="JUSTIFY">Step one is to create a new SuperUser.  This SuperUser will not have complete control of the W3-Auth system.  We will create a SuperUser with limited power who will be responsible for the addition and deletion of users from the new namespace (bill in our example).  To create the new SuperUser, enter the SuperUser namespace management area by selecting the SuperUser namespace from the main menu. You will be presented with the SuperUser Management menu depicted below.  By selecting the User Management option from the menu you will be presented with a list of the currently defined users in the namespace (only bambi at this time).  Select the Add option and then click Execute to add a new user.  You will be prompted for the new users details (for bill in this case).  Enter the details and click Execute to create the new user.</P>
<P ALIGN="JUSTIFY">Step two is to create the new namespace.  To do this we again enter the SuperUser namespace from the main menu. From the menu select the &quot;Namespace Management&quot; option.  The browser will now show you a list of currently defined namespaces (just the SuperUser namespace in this case).  To create a new namespace, select &quot;Add&quot; and then click the &quot;Execute&quot; button.  You will be prompted for the name of the new namespace, a description, and a list of namespace administrators.  In our example, the name of the namespace is &quot;Trident&quot;, a description could be &quot;Hughes Tech. Trident System&quot; and the administrator would be &quot;bill&quot;.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image3.gif" WIDTH=289 HEIGHT=275>Now that the new namespace has been defined we must define what privileges our administrator, bill, has over the namespace.  To do this, enter the SuperUser namespace menu, choose &quot;Privilege Management&quot;, and then choose to edit bills privileges.   At this time you will be presented with a list of namespaces of which bill is an administrator (only &quot;trident&quot; in our example).  Select trident from the list to edit the privileges bill has for that namespace.  You will see that bill currently has no privileges in the trident namespace.  You can enable individual privileges by selecting the check-box associated with the privilege.  </P>
<P ALIGN="JUSTIFY">In our example, we want bill to be able to manage users and user groups within the trident namespace.  To achieve our goal, select &quot;User Management&quot; and &quot;Group Member Management&quot; from the list.  Your screen should look like the screen shot below.  Bill could now run the w3-auth program and add users to the Trident namespace.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">We have stated that bill can manage the users of the trident namespace but that is all.  There are other operations that need to be performed on the namespace that bill is not allowed to do (such as defining a secure area).  As bambi is the system administrator, it is up to him to perform these tasks.  Currently, bambi has no privileges for the trident namespace.  To enable them, use the Namespace Management option from the SuperUser menu to edit the definition of the trident namespace and add bambi as a namespace administrator.  </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image4.gif" WIDTH=296 HEIGHT=281>Once that is complete, use the Privilege Management option to edit bambis privileges for the trident namespace and enable all privileges. Now that bambi has permission to modify the trident namespace, return to the main menu and enter the trident namespace (it will now be visible to bambi as he is listed as an administrator).   </P>
<P ALIGN="JUSTIFY">The Authentication Management menu shown on the next page will be displayed in your browser.  Before we can proceed much further we must define a couple of user groups.  User groups are used in the definition of the access control to define which users defined in the namespace have access to the secure area.</P>
<P ALIGN="JUSTIFY">In our example we want to define two groups, a general user group and an admin group.  To do this select the Group Management option and add a group called &quot;users&quot; with bill as the administrator.  Repeat the process and create another group called &quot;admin&quot; also with bill as the administrator.  Even though bill was given group member management privileges, he can only manage group members in groups for which he is defined as an administrator.</P>
<P ALIGN="JUSTIFY">Once the groups are created we can define the secure area for our W3-mSQL based application.  Our application offers two classes of access.  Primarily, the application allows a general user to query the data contained in the database.  Secondly, it offers a set of pages that allow the database to be modified.  The main application is installed in a directory called /trident in our web document tree (i.e. http://your.host/trident) while the administrative pages are located in /trident/admin.  We wish to view these as separate areas in terms of access control even though they are part of the same application.  A general user will be allowed to access the query pages but only a restricted set of users will be allowed to access the administrative pages.</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image5.gif" WIDTH=291 HEIGHT=276>To tighten the security even further, we have decided to incorporate host based access control as well.  Access to the administrative pages should only be granted if the access request comes from a machine in our domain (Hughes.com.au) regardless of the identity of the user attempting the access.  </P>
<P ALIGN="JUSTIFY">Now that we have decided the access control policy for our application, implementing it is as easy as clicking the mouse a few times.  To start the process we must enter the trident namespace from the main menu and select Area Management from the Authentication Management menu.  The area management facility provides the same familiar interface as the other management options.  To create the new area we simply select the Add option and click Execute.  We will be prompted for an area name, an area URL and some access control options.  For this example we will create the general access area first and give it a name of &quot;Trident User&quot;.  The URL field requires only the path element of the URL, not the entire URL.  In this case we would specify /trident as the URL.</P>
<P ALIGN="JUSTIFY">The next step is to add the access control elements to the area definition.  The area definition screen is shown below. The form shown on the screen allows us to specify up to five elements to the access control list for the area. By default, each element is flagged as being Inactive.  To enable an element, simply change the Index value from Inactive to the numeric value on the menu.  You should define access control elements from the top of the list without leaving any inactive elements between active elements so simply activate the first element for this example.</P>
<P ALIGN="JUSTIFY">For our example we want to allow access to the area to anyone in the &quot;users&quot; group.  Unlike the admin area, we are not going to place any restriction on the originating host of the connection.  To achieve this configuration we simply select the &quot;users&quot; group from the group menu and set the host field to * (indicating any host).  The complete form is shown below.</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image6.gif" WIDTH=289 HEIGHT=275>The access control field of the element can contain either a hostname based expression or an IP address based expression (including a wildcard in either form of expression).  To restrict access to only machines in the Hughes.com.au domain (as decided was the policy for the admin section), we would set the value of the Access Control field to  *.Hughes.com.au.  Similarly, if we wished to restrict access to machines on a particular IP subnet, we could use something like 192.168.1.*</P>
<P ALIGN="JUSTIFY">In a similar manner, we could allow access to any person if they are coming from a specified location.  To do this, simply leave the Access Group as &quot;** Public **&quot; and set the Access Control to the correct hostname of IP address expression.  In such a configuration, the user will only be prompted for a username and password if they attempt to access the pages from a machine not matching the Access Control expression.  If we activate no other Access Control elements, the user would always be rejected as no user groups were specified in the Access Control Elements.</P>
<P ALIGN="JUSTIFY">By using a combination of access control elements we can achieve very fine-grained control over who accesses the pages.  If, for example, there was a group of people at a remote location that required access to the pages from their company network (foo.com), you could define a new group called remote and activate a second access control element with an access group of remote and an access control of *.foo.com.  Such a configuration would allow access if the connection attempt matched either of the entries.</P>
<P ALIGN="JUSTIFY">Once the Trident User area has been created the process should be repeated for the Trident Admin area.  For the admin area, we would define the URL as /trident/admin and set a single Access Control element setting the Access Group to &quot;admin&quot; and the Access Control to *.Hughes.om.au.</P>
<P ALIGN="JUSTIFY">The only remaining task is the creation of the actual users: &quot;fred&quot; and &quot;john&quot; in our example.  The responsibility for user management was assigned to &quot;bill&quot; and his privileges were set so that he could create users and also add users to groups (group member management).  Bill can now complete the job by accessing the W3-Auth program, entering the trident namespace, and using the User Management and Group Member Management menu options.  If either of the new users is allowed to access the admin features of our application then they should be added to the &quot;admin&quot; group as well as the normal &quot;users&quot; group.  Simply adding them to the admin group will provide them access to the admin pages.</P>
<P ALIGN="JUSTIFY"><IMG SRC="Image1.gif" WIDTH=57 HEIGHT=47>A final note to remember about W3-Auth access control is that access control must be enabled on a per directory basis.  To enable access control you must create a file called &quot;.w3-auth&quot; in every directory within the area that is to be protected.  The reason for this requirement is to boost performance.  W3-mSQL simply checks for the file while it is loading the requested page.  If the file exists, it then starts querying the database for W3-Auth configuration details and trying to match the requested URL with an area definition.  If the directory is not being covered by W3-Auth this is a waste of valuable time.  </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767780">Appendix A - New Features in mSQL 2.0</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Mini SQL 2.0 is the second generation of the mSQL database system. The first generation product, mSQL 1.x, was designed to provide high speed access to small data sets. The original goal was to perform 100 basic operations per second on an average UNIX workstation with small data sets using very few system resources (i.e. memory and CPU cycles). The original design goal was met and the software has proven to be popular because of this functionality. </P>
<P ALIGN="JUSTIFY">During mSQL's life, people have used it for applications far beyond the scope of the original design. These high-end applications, containing up to 1 million rows of data, showed a need for better handling of complex queries and large data sets if the package was to be used in this way. The second generation of the mSQL server has been designed to suit these high-end applications while maintaining the original design goals of mSQL 1. It has been designed to meet three main criteria </P></DIR>
</DIR>
</DIR>


<UL><DIR>
<DIR>
<DIR>
<DIR>


<UL>
<P ALIGN="JUSTIFY"><LI>Provide comparable performance for simple operations as mSQL 1.x. </LI></P>
<P ALIGN="JUSTIFY"><LI>Provide rapid access to large databases and complex operations. </LI></P>
<P ALIGN="JUSTIFY"><LI>Provide more of the functionality outlined in the ANSI SQL specification. </LI></P></UL>
</DIR>
</DIR>
</DIR>
</DIR>
</UL>

<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767781">Enhanced Indexing</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">One of the major flaws of mSQL 1.0 when used for larger applications was the simplistic indexing support. The original server supported only a single primary key per table and the key could consist of only one field. The internal use of the key was restricted to queries using a simple equality condition. As such, the vast majority of queries were processed without the aid of the key. </P>
<P ALIGN="JUSTIFY">mSQL 2.0 provides much more sophisticated indexing support. Each table can have multiple indices defined for its data, with each index consisting of one to ten fields. Any index can be designated as a unique or non-unique index. The index information is stored in a series of AVL Tree structures that are mapped into the virtual memory address space of the mSQL server process. The use of AVL Trees in this way ensures that access to key data is extremely fast. </P>
<P ALIGN="JUSTIFY">Although the Beta 1 release of mSQL 2.0 includes only the AVL indexing scheme, the database engine itself has been written to support multiple indexing formats. The underlying format of the index can be specified in the SQL command used to create the index. Other indexing schemes are under development and will be made available in subsequent releases of mSQL 2.0. </P>
<P ALIGN="JUSTIFY">To aid in the use of the indices during query execution, a layer of abstraction know as the "candidate rows" system has been introduced into the server. The concept of the candidate rows abstraction is that during query processing, the module performing the query requests the next row from the data table that is a candidate for the selection criteria specified in the query. The requesting module is not aware of the mechanisms used to determine how that row was chosen or accessed. The "candidate row" routines are responsible for determining the best access method (based on the conditions specified in the where clause) and for retrieving the data rows as they are requested. This ensures that the optimum access method is used whenever a row of data is accessed without replicating the access logic in each module and without any "special case" algorithms. </P>
<P ALIGN="JUSTIFY">Because the candidate row abstraction provides a single logic path for the acquisition of data rows, it can also be used to optimise the query. A simple query optimiser has been included in the candidate row abstraction and the functionality of the optimiser will be enhanced over time. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

<P ALIGN="JUSTIFY"><A NAME="_Toc393767782">Data Types</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Another of the limiting factors of the performance of mSQL 1.0 was the size to which tables grew. Given an increasing number of rows, the amount of data that needed to be manipulated in memory increased proportionally. Unfortunately, the fixed length field structure of mSQL 1.0 usually forced a lot of white space and field padding to be included in the data. </P>
<P ALIGN="JUSTIFY">To overcome this problem, mSQL 2.0 includes support for a variable length char type (text). The text type allows an unrestricted amount of data to be inserted into a field by using an overflow buffer scheme to hold data beyond the specified size of the field. This provides the best of both worlds in that the database designer can specify the average size of a char field ensuring that in most cases, the data will be held in the data table. If a value is inserted that is longer than average, it will be split between that data table and the overflow buffers. This eliminates the need to specify overly large fields (e.g. 255 character) for storage of URLs and filenames. </P>
<P ALIGN="JUSTIFY">To provide a more complete SQL environment, future releases of mSQL will include more of the "standard" data types defined by the SQL standard. These will include date/time, currency, and various other types that are provided by the larger database systems. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767783">System Variable / Pseudo Fields</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The 2.0 engine includes a framework for supporting system variable or pseudo fields. These fields are data elements maintained by the engine itself but are accessed using a normal select call. Some of the data pertains to an entire table, some to a particular row, and some to the current session. The 2.0 engine provides support for the following system variables </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>
</FONT>
<P ALIGN="RIGHT"><TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=631>
<TR><TD WIDTH="16%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Name</B></FONT></TD>
<TD WIDTH="84%" VALIGN="TOP" BGCOLOR="#ffffff">
<B><FONT SIZE=2><P ALIGN="CENTER">Description</B></FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">_rowid</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">An internal value used to identify a row based on its location. The _rowid field can be used in where clauses during updates and deletes to specify a particular row. </FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">_timestamp</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">An internal value indicating when the row was last modified</FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">_sysdate</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The current time and date on the machine running the database engine returned in standard UNIX time format (e.g. seconds since the epoch) </FONT></TD>
</TR>
<TR><TD WIDTH="16%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">_user</FONT></TD>
<TD WIDTH="84%" VALIGN="TOP">
<FONT SIZE=2><P ALIGN="JUSTIFY">The username associated with the session over which the query was submitted </FONT></TD>
</TR>
</TABLE>
</P>

<FONT SIZE=2><P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767784">Sequences</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">To overcome the problem of trying to manage sequences in client application code, mSQL 2.0 provides in-built, atomic operations for accessing and managing sequences. A sequence is a numeric counter that is automatically adjusted to the next value in the sequence each time it is accessed. The sequence is created using a version of the SQL CREATE command and can be created with a user defined initial value and also a user defined step value (i.e. the value added to the sequence after each access. </P>
<P ALIGN="JUSTIFY">Any table can have a sequence created for it but a table can only contain a single sequence. Once the sequence has been created, accessing the sequence value is achieved using the _seq system variable, that is, by using a query such as </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>select _seq from foo</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The current sequence value is returned and the sequence is updated to the next value in the sequence. Access to and modification of the sequence is atomic. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767785">Complex Expressions</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Unlike version 1.x of mSQL, 2.0 supports the notion of complex expressions in where clauses (i.e. the use of parenthesis and sub conditions in a condition). This removes a major limitation in mSQL as it was impossible to perform queries like </P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Helvetica-Narrow" SIZE=1><P>SELECT name FROM staff </P>
<P>WHERE (staff_id &lt;100 OR staff_id &gt; 200) </P>
<P>AND dept = 'finance'</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>

</FONT><FONT SIZE=2><P ALIGN="JUSTIFY">mSQL 2.0 supports the nesting of sub-conditions to any depth and there can be any number of sub-conditions in the where clause. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767786">Regular Expressions</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">ANSI SQL defines a very simple regular expression language for use in matching data with the LIKE operator. mSQL 1.x implemented a superset of this functionality by providing access to the complete UNIX regular expression syntax in a LIKE clause. Processing a UNIX regular expression is far more "expensive" than processing the simplistic functionality defined in the ANSI specification and as such LIKE based searching was quite slow in 1.x. To improve this, mSQL 2.0 provides a standard SQL LIKE operator and also offers the extended UNIX syntax via the RLIKE (i.e. regexp LIKE) operator. Most queries will require only the simple functionality offered by the standard SQL LIKE but the extended functionality is retained for compatibility. It should be noted that the new LIKE operator is much faster than the full UNIX version offered by 1.x. </P>
<P ALIGN="JUSTIFY">One of the main uses of the UNIX regular expression syntax in 1.x was for performing case insensitive searches. In standard SQL, the way to perform case insensitive searches is to use functions like UPCASE() in the query. 2.0 offers a non-standard operator known as CLIKE which implements a case-insensitive version of the standard SQL LIKE operator which both solves the problem and provides much better performance. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767787">ORDER BY and DISTINCT</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Most "real-world" applications utilise the sorting and DISTINCT functionality of an SQL server when presenting a list of data returned from the database. The implementation of ORDER BY and DISTINCT in mSQL 1.x proved to be a performance bottleneck for serious applications. To overcome this, 2.0 offers a new sorting implementation (based on the quicksort algorithm) and also has a faster DISTINCT implementation. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767788">Client Connections</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">As the popularity of mSQL for use behind web servers increased it became apparent that the limit of 24 simultaneous client connections was a major problem. 2.0 overcomes this by reconfiguring the server's internal client connection tables at run-time to handle the maximum number of connections possible based on the operating system and the way the kernel is configured. On an average OS, mSQL 2.0 will reconfigure itself to handle over 200 simultaneous client connections. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767789">Run-time Configuration</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Configuration details, such as the location of the UNIX and TCP ports etc., was hard-coded into the server and API library in mSQL 1.x. To provide more flexibility, all configuration details are now included in a configuration file that is loaded at run-time by both the server and any client applications that talk to the server. By modifying a value in the config file, all applications will use the new value when they are next executed. All programs also offer a run-time flag to allow the loading of a non-default configuration file to allow for testing of new servers or applications. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">To reduce the risk associated with root-owned daemon processes, mSQL 2.0 can be configured to run as any user (via the config file). By default, the server will run as a user called msql once it has started. If the server is run as root it will call setuid() to change to the desired user once it has initialised itself and performed any startup operations. </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767790">Lite &amp; W3-mSQL 2.0</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The mSQL 2.0 includes the Lite and W3-mSQL tools to aid in the development of applications. W3-mSQL 2.0, the second generation WWW interface package, is included as a standard tool. The new W3-mSQL code provides a complete scripting language, with full access to the mSQL API, within an HTML tag. This tool can be used to develop sophisticated GUI based applications that are platform independent and available as shared resources on a network. Along with the mSQL API, a library of nearly 60 other functions, including file I/O, strings handling and date/time manipulation are available to the scripts within a W3-mSQL enhanced web page. </P>
<P ALIGN="JUSTIFY">To solve another problem associated with delivering "real" applications over the web, W3-mSQL provides an enhanced and flexible authentication system. Any page that is accessed via W3-mSQL is subjected to the new W3-auth access scrutiny. Access can be restricted via a combination of username/passwd and requesting host. Configuration of the security system, including management of user groups, definition of secure areas, and creation of authorised users, is via a graphical interface accessed via a web page. </P>
<P ALIGN="JUSTIFY">Access to mSQL from scripting languages has become popular and virtually all major scripting languages provide an interface to the original mSQL server. Support for script based access to mSQL becomes standard in mSQL 2.0 with the inclusion of its own scripting language. The language, called Lite, is a stand-alone version of the language provided by W3-mSQL (i.e. the language that W3-mSQL offers inside the special HTML tags is Lite) and includes access to the mSQL API and the other functions mentioned above. Lite, as its name implies, is a lightweight language yet provides a powerful and flexible programming environment. The syntax of the language will be very familiar to C programmers (and ESL programmers) and provides shell-like ease of use. A future release of Lite will include support for ASCII forms to provide a rapid development environment for non-graphical mSQL-based applications. </P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767791">Other tools</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">mSQL 2.0 is bundled with a couple of new tools. To aid migration of data to and from mSQL, two new utilities have been added to the distribution for the 2.0 release. msqlimport and msqlexport provide a mechanism for the import and export of data as formatted text files. Migrating data from other databases into mSQL 2.0 will require just a simple export from the source database and a subsequent import into the new mSQL database. The tools have been developed to be flexible enough to support virtually any text based formatting of the exported data. </P>
<P ALIGN="JUSTIFY">Other familiar tools have been modified to reflect the functionality of mSQL 2.0. relshow can provide detailed information about all the table structure elements, including the indices defined on tables. msqladmin has been modified to provide statistical information on a per connection basis (so you can monitor who's doing what and when). </P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767792">Appendix B - mSQL Error Messages</A></P><DIR>
<DIR>
<DIR>

</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Listed below is a complete set of the error messages generated by the mSQL database engine and the client API library.  Accompanying each error message is an indication of the cause of the error and actions that you can take to resolve the problem. The errors relate to user-generated problems, such as incorrect SQL query syntax, and also system related problems, such as running out of disk space.  A user will not normally see many of these errors.</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767793">API Library Error Messages</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Bad packet received from server</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The server process received a data request that was incorrectly formatted.  Such requests are ignored by the server and are probably caused by using an incorrect implementation of the client API library.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't find your username. Who are you?</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The mSQL client library has attempted to translate the User ID (Unix UID) of the process running the client application into a username.  The attempt failed.  This will be the result if the UID of the client process is not listed in the systems password file.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't create UNIX socket</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The API library has attempted to communicate with an mSQL server running on the local machine.  In doing so, it tried to create a UNIX domain socket over which the client / server communications would pass.  The attempt to create this socket failed.  If this error message is generated when starting the server process, it implies that the user running the server does not have permission to create the UNIX socket.  Check the msql.conf file to determine whether the mSQL_User field and the UNIX_Port fields are set correctly.  If the error is generated by a client application it can indicate that the client process has too many files open at the same time.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't connect to local mSQL server</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made to form a connection with an mSQL server running on the local machine.  The attempt failed.  The mSQL server process is probably not running on this machine.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't connect to mSQL server on </P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to connect to an mSQL server process running on a remote machine failed.  This is usually due to not having an mSQL server running on the remote machine</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't create IP socket</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The API library attempted to create a TCP/IP socket for use in communicating with an mSQL process on a remote machine.  The attempt failed.  This is commonly caused by having too many open files in the client application.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">mSQL server has gone away</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">While the API library was communicating with an mSQL server process, the server process closed the client / server connection.  This can be caused by the server process being terminated, the machine on which the server is running being rebooted, or a network failure if the server is on a remote machine.</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Protocol mismatch. Server Version = x Client Version = y</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The version of the mSQL client / server protocol used by the client API library and the server process do not match.  Upgrading the server software but not relinking the client applications that are communicating with the server can cause this problem.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown mSQL error</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An error occurred while communicating with the server process but the server was not able to determine the cause of the error.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown mSQL Server Host </P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The hostname passed to the msqlConnect( ) function could not be resolved into an IP address.  Ensure that the listed machine is in the nameserver or hosts file of the machine running the client applications</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>

</FONT><B><FONT FACE="Helvetica" SIZE=5><P ALIGN="JUSTIFY"><A NAME="_Toc393767794">Server Error Messages</A></P><DIR>
<DIR>
<DIR>

</FONT><FONT FACE="Arial"><P ALIGN="JUSTIFY">Access to database denied</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to access a database was rejected based on the contents of the access control list for that database.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Bad handshake</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The initial handshake during connection establishment between a client application and the mSQL server process was incorrectly formatted.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Bad order field. Field "x" was not selected</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The field x was used in an &quot;order by&quot; statement but it was not included in the list of fields selected from the table.  You can only order by a field you have selected.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Bad type for comparison of 'x</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The value used within the where condition associated with the field x was of an incompatible type.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't perform LIKE on int value</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made to perform a regular expression match on an integer value.  Regex searching can only be performed on character fields.</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't perform LIKE on real value"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made to perform a regular expression match on an real value.  Regex searching can only be performed on character fields.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't get hostname for your address</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The server process tried to resolve a hostname from the IP address of the machine running the client application.  This will occur if the client machine is not listed in the nameserver.  You may overcome this problem by setting the Host_Lookup field of msql.conf to false.  Note that disabling this option will effect access control for the databases as the hostname of the client is used during ACL tests.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't open directory "x" (y)</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to access the directory listed as x was not successful.  The system error message is returned as y.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Can't use TEXT fields in LIKE comparison</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A select query attempted to perform a regular expression match against a TEXT field.  TEXT fields cannot be used in regex matches.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Couldn't create temporary table (y)</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to create the files associated with a temporary table failed during the execution of a query.  This is usually caused by having the permission of the msqldb/.tmp directory in the installation directory set incorrectly.  The system error message is returned as y.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Couldn't open data file for x (y)</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to open the data file for a table called x in the currently selected database failed.  The system error message is returned as y.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Data write failed (x)</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A write operation failed while attempting to store data into a table or temporary table.  The system error message describing the error is returned as x.  The usual reason for this problem is lack of disk space during an insert operation or a multi-table join that produced an overly large result set.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Error creating table file for "x" (y)</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Creation of the data file for table x failed.  A description of the error is returned in y</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Error reading table "x" definition (y)</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An error was encountered while the server attempted to read the table definition for the table called x in the currently selected database.  The system error message is returned as y.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Field "x" cannot be null</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made during either an insert or an update operation to set the value of a NOT NULL field to NULL.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Index field "x" cannot be NULL</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to insert a NULL value into an index was rejected by the server.  Indices cannot be set to NULL.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Index condition for "x" cannot be NULL</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">Because indices cannot contain NULL values, the attempt to use a NULL condition for an index lookup was rejected.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Invalid date format "x"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The value &quot;x&quot; is not a valid date format and was rejected by the server.  This may occur when inserting into a date field, updating the value of a date field, or when using a date value in a where condition</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Invalid time format "x"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The value &quot;x&quot; is not a valid time format and was rejected by the server.  This may occur when inserting into a time field, updating the value of a time field, or when using a time value in a where condition</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Literal value for 'x' is wrong type</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">During either an insert or an update operation, an attempt was made to set the value of a field to a type that was not compatible with the defined type of the field (e.g. setting an integer field to a character value).</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">No Database Selected</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A query was sent to the server before a database had been selected.  The client application must call the msqlSelectDB function before submitting any queries.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">No value specified for field 'x'</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An insert operation sent to the database engine did not include a value for field x.  Either the field x was specified in the field list and not enough values were provided or the number of values provided did not match the total number of fields in the table.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Non unique value for unique index</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A value that was assigned to a unique index via either an insert or an update clause attempted to insert a duplicate value. </P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Out of memory for temporary table</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt by the server to malloc a memory segment was refused during the creation of a temporary table (during execution of a query).</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Permission denied</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to access a database in a particular manner was refused due to the ACL configuration of the selected database.  Usually, write access (i.e. inserts or updates) are rejected because the database is listed as read-only for that client.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Reference to un-selected table "x"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A select query referenced a variable from table x when x was not listed as a table in the select clause.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Table "x" exists"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to create a table called x failed because the table already exists.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Too many connections</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt to connect to the mSQL server process was refused because the maximum number of simultaneous client connections has been reached.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Too many fields in query</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The query attempted to reference more fields in a single query than the server permits.  By default, up to 75 fields can be referenced in the same query.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Too many fields in condition</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The number of conditions included in the where clause exceeded the allowed maximum of 75.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown command</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A unknown client / server protocol command was received by the server and was rejected.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown database "x"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made to access a database called x although no such database is defined on the server</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown table "x"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made to access a table called x although no such table is defined in the currently selected database.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown field "x.y"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An attempt was made to reference a field called x in a table called y.  Table y of the currently selected database does not contain a field called x.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unknown system variable "x"</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">A query referenced a system variable called x when no such system variable exists.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unqualified field in comparison</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">An unqualified field name was used in the where clause of a join.  You must fully qualify all field names if you reference more than one table.</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">Unqualified field "x" in join</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The field x was not fully qualified in the field list of a join.  All fields referenced in a join must be fully qualified.</P>
</FONT><B><FONT FACE="Arial"><P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">Value for "x" is too large</P>
</B></FONT><FONT SIZE=2><P ALIGN="JUSTIFY">The value provided for field x in either an insert or an update clause was larger than the defined length of the field</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
</DIR>
</DIR>