MySQL++

Check-in Differences
Login

Check-in Differences

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From d9c6b79b99609eea To c9afe0650e7bf849

2017-10-10
21:10
Removed broken symlink check-in: 13f6b59c1e user: tangent tags: v2.3.2-modern
2017-09-09
00:06
Fixed a dependency declaration in the old 2.3.2 spec file that caused complaints if you tried to install the resulting -devel RPM. check-in: d9c6b79b99 user: tangent tags: v2.3.2-modern
2017-09-08
18:30
Added a #include needed by Ubuntu 16.04 check-in: be32e63bc1 user: tangent tags: v2.3.2-modern
2000-02-06
23:00
Version 1.6.0 check-in: 6c378b5890 user: tangent tags: trunk, v1.6.0
2000-01-06
19:28
Version 1.5.1 check-in: c9afe0650e user: tangent tags: trunk, v1.5.1
1999-11-25
14:40
Version 1.4 check-in: bc5d0a2f8e user: tangent tags: trunk, v1.4

Added AUTHORS.
Deleted Bakefiles.bkgen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0" ?>
<bakefile-gen>
    <input>
        ./mysql++.bkl
    </input>

    <!-- List of output formats to generate: -->
    <add-formats>
        autoconf,msvc6prj,mingw
    </add-formats>

    <add-flags formats="mingw">
        -o$(INPUT_FILE_DIR)/Makefile.mingw
    </add-flags>
</bakefile-gen>
Changes to COPYING.
1
2
3
4
5

6
7
8
9
10





1





-
-
-
-
-
+
-
-
-
-
-
The MySQL++ library proper and the reference manual derived from
comments in the library source code are licensed under the GNU Lesser
General Public License. A copy is provided in this directory, in the
file LICENSE.

/usr/share/automake/COPYING
The MySQL++ User Manual is licensed under a unique license derived from
the Linux Documentation Project License. (The only changes are due to
the fact that the User Manual isn't actually part of the LDP, so a lot
of the language in the LDPL doesn't make sense when applied to the user
manual.) This license is provided in the file doc/userman/LICENSE.
Added COPYRIGHT.























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The Mysql++ API is copyright 1998 by Kevin Atkinson and is released
under the LGPL license for now.

The intent of doing this is allow developers to use my library to
develop commercial programs and to allow it it be distributed with
commercial databases.

However if you do use it to develop a commercial program a small
donation to me would be greatly appreshated.  Your donation will will
encourage me to continue to work on improving this API and also
encourage me to contune to keep it under the LGPL.  Please send
donations too.
  Kevin Atkinson
  7962 Helmart Dr.
  Laurel, MD 20723

I reserve the right to change the license to future versions of the
library if I do not get suffecent pay-back to my work.  However, it is
my promise to you that it will never become more restrictive than the
GPL (not LGPL) licence.

You can contact me at kevinatk@home.com or (301) 498-3290 or at 
7962 Helmart Dr./Laurel, MD 20723.
Deleted CREDITS.
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





















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
MySQL++ was created by Kevin Atkinson during 1998. From version 1.0
(released in June 1999) through 1.7.9 (May 2001), the primary maintainer
was Sinisa Milivojevic <sinisa@mysql.com>. Neither Kevin nor Sinisa
are currently involved in MySQL++ development. The current maintainer
is Warren Young <mysqlpp@etr-usa.com>, starting with version 1.7.10 in
August of 2004.

For a fuller account of the library's history, see the first chapter
of the user manual.  For the nitty-gritty details, see the ChangeLog
in the root package directory.  ChangeLog items since 1.7.9 that
aren't attributed to anyone else were done by Warren Young.


Other contributors of note since 1.7.10:

	Chris Frey <cdfrey@netdirect.ca>: Lots of GCC warning fixes for
	the bleeding-edge compiler versions, and Gentoo ebuild support.
	Also, if there were a "steering committee" for MySQL++, he'd be
	on it.

	Mark Meredino <Mark_Merendino@cnt.com>: Several fixes and
	additions, including a lot of work on Microsoft Visual C++
	compatibility, and discoveries made while spelunking in the
	library.

	Evan Wies <evan@athenacr.com>: Contributed several C++ code
	style cleanups.

	Arnon Jalon <Arnon.Jalon@247RealMedia.com>: Added the multi-query
	result set handling features, and multiquery example to demonstrate
	it.

	Korolyov Ilya has submitted several patches in many different
	areas of the library.

	Remi Collet <Liste@FamilleCollet.com> is maintaining offical
	RPMs for Fedora, with other systems on the way.  His work has
	improved the RPM spec file we distribute greatly.

	Joel Fielder <joel.fielder@switchplane.com> came up with the
	original idea for Query::for_each() and Query::store_in(),
	provided the basis for examples/for_each.cpp, and provided
	a fix for exception flag propagation in Query.


Here are the personal credits from the old 1.7.9 documentation,
apparently written by Kevin Atkinson:

	Chris Halverson - For helping me get it to compile under Solaris.

	Fredric Fredricson - For a long talk about automatic conversions.

	Michael Widenius - MySQL developer who has been very supportive of
		my efforts.

	Paul J. Lucas - For the original idea of treating the query object
		like a stream.

	Scott Barron - For helping me with the shared libraries.

	Jools Enticknap - For giving me the Template Queries idea.

	M. S. Sriram - For a detailed dission of how the Template Queries
		should be implemented, the suggestion to throw exceptions on bad
		queries, and the idea of having a back-end independent query
		object (ie SQLQuery).

	Sinisa Milivojevic - For becoming the new offical maintainer.

	D. Hawkins and E. Loic for their autoconf + automake contribution.


See the ChangeLog for further credits, and details about the differences
between the many versions of this library.


Please do not email any of these people with general questions about
MySQL++. All of us who are still active in MySQL++ development read the
mailing list, so questions sent there do get to us:

	http://lists.mysql.com/plusplus

The mailing list is superior to private email because the answers are
archived for future questioners to find, and because you are likely to
get answers from more people.
Changes to ChangeLog.
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


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



































































































-
-
+
-
-

-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
+
-

-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
+
-
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
-
+
-
-
-
-
+
-
-
-
+
-
-

-
-
-
-

-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
+
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
+
+
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
-
-
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2.3.2, 2007.07.11 (r1669)

2000-01-06  Dale Hawkins  <dhawkins@cdrgts.com>
	o Previous release's const_string change caused more problems
	  than it fixed.  This release contains the real fix. :)

	o New Connection::set_option() handling deals with the multi
	  statements option correctly again.  examples/multiquery now
	  runs again as a result.

	* acconfig.h: New file.  Lets me define the library versioning.
	o Added new unit testing script, called dtest.	See the
	  HACKERS file for details.  (This tool caught the previous
	  two problems!)

	o Squished a GCC pedantic warning.  Thanks for the patch go to
	  Andrew Sayers.


2.3.1, 2007.07.10 (r1659) The "After the Fireworks" release

	o const_string objects now keep a copy of their data, not
	  just a pointer to it.  This is less efficient, but necessary
	  to allow SSQLS to work with BLOBs.  Without this, we were
	  seeing segfaults due to accessing freed memory pointed to
	  by the const_string, because the underlying object went
	  out of scope.

	o Fixed many more potential embedded null handling problems
	  in manip.h.

	o MySQL++ can now optionally reference MySQL C API headers as
	  being in a mysql subdirectory, a common thing on *ix systems,
	  by defining MYSQLPP_MYSQL_HEADERS_BURIED before #including
	  mysql++.h.

	o Restored ColData_Tmpl<T>::get_string(), removed in v2.3.0,
	  along with warnings in the docs saying why you don't want
	  to use it, and what your alternatives are.

	o VC++ and MinGW builds now define the HAVE_MYSQL_SSL_SET
	  macro, which lets you use the C API's SSL features.
	  This assumes your C API library does actually have these
	  features enabled, which is the case with the official binary
	  releases on Windows.	(Builds on *ix systems continue to
	  test for these features at configure time.)

    o Fixed simple examples-only Makefile generation, for RPMs.


2.3.0, 2007.07.02 (r1645)

    o Added Query::for_each() and Query::store_if() methods
      proposed by Joel Fielder, and added examples for each.

    o It's now possible to store BLOB data in an SSQLS.  It's not
      foolproof, so added a section to the user manual (5.9) to
      document the method.  Also, changed examples/cgi_jpeg to use
      this new mechanism, instead of the ugly "raw row data" method
      it used to use.

    o Revamped Connection::set_option() handling.  These options
      used to be queued up, and applied only just before actually
      establishing the connection.  This made error reporting less
      helpful because the diagnostic was separated from the cause.
      Plus, the error messages were misleading to begin with.  Now,
      set_option() takes effect immediately if the connection is not
      yet up (excepting one special option that can actually be set
      after the connection is up) and issues better diagnostics when
      it detects errors.

    o Connection::connect() used to set a few options in such a
      way that the user couldn't override them.  Now it's smart enough
      to set them with the desired default values only when we see
      that the user hasn't given them other values.

    o SQLString can now be initialized from a mysqlpp::null,
      giving a "NULL" string.  This is useful for template queries.
      Patch by Michael Hanselmann.

    o resetdb error message about mixing library and header version
      numbers is now more explicit.

    o Changed BadConversion exception's "what" message text to be
      more like the other exceptions.  The inconsistency lead one
      to incorrectly copy-paste code from another exception handler,
      expecting it to behave the same way.  Now it does.

    o Added Row::raw_size(), as a shortcut for Row::at().size().

    o ssqls-pretty now detects when it's being run from within
      the MySQL++ distribution tree and gives a different -I flag
      to the compiler, so that it picks up the distribution headers
      instead of those that may be on the system already.

	o The quote manipulator now works for char[] correctly.
	  Thanks for this patch go to Andrew Sayers.  (It's always
	  worked for char*, but C++ doesn't consider that to be the
	  same type, so it used the generic quote handling path,
	  which doesn't do anything for char[].)

    o Fixed a build bug on older Solaris versions where the
      test for the C API library was erroneously failing, stopping
      the configuration process.

    o Simplified mysql_shutdown() level argument detection.
      Already had to do a version number ifdef check for the
      Windows case, so there's really no point to doing it with
      autoconf on Unixy platforms.  Moved version number check
      into lib/connection.cpp, and nuked the separate autoconf and
      Windows tests.

    o Removed dependency of sql_types.h on myset.h and (indirectly)
      datetime.h.  Now we only define sql_* typedef aliases for those
      MySQL++ types if the headers are included before sql_types.h.

    o Fixed a typo in one of the storein_sequence() template
      overloads, which is apparently rarely (or never?) used, because
      no one reported the compiler error you'd get if you tried.

    o Fixed a few more embedded null handling problems.

    o ColData used to keep two copies of all data it held.
      Now it keeps just one.

    o Fixed install.bat script to track the unified Bakefile change
      and the lack of separate debug and release builds under MinGW.

	* autogen.sh: Boilerplate configuration jump-start script.
    o Yet another STLport + Query memory leak fix.

    o Squished a warning in newer GCCs having to do with identifier
      shadowing.  Patch by Jonathan Wakely.

2000-01-04  Dale Hawkins  <dhawkins@cdrgts.com>
    o Fixed a null-termination bug in Query::parse().  If you
      somehow constructed a query string without a terminating null
      character, then tried to parse it as a template query, it could
      walk off the end of the string.  Patch by Worster Chen.

    o Removed MYSQLPP_EXPORT tag from FieldNames and FieldTypes
      class declarations, as this can cause problems in programs
      that use vector<string> in VC++.  It has to do with multiply
      defined templates, since these classes derive from that
      template, and VC++ can't resolve the conflict without help.
      Since these classes aren't actually used outside the library,
      this shouldn't cause a problem.  Patch by Nils Woetzel.

    o Partial fix to Doxygen PDF build on RHEL4 and 5.  Needs
      hand-coaxing to complete successfully on RHEL4, and doesn't
      yet work at all on RHEL5.

    o Shortened the "no*" options to the bootstrap script, so that
      the usage message fits on a single line.

    o Added "nodoc" bootstrap script option, for disabling the
      documentation build during the dist target build.  Allows for
      building binary RPMs on CentOS 5.0, where doc building is
      currently broken.

    o Removed the updel example program.  It was kind of silly,
      and if you were to rewrite it today, you'd use for_each() anyway.

    o Lots of documentation improvements.


2.2.3, 2007.04.17 (r1538) The "Tax Day" release

    o Previous version left examples/vstudio/* out of the tarball
      by accident.

    o Improved generation of RPM temporary build directory path
      name generation.  Was using a hacked variant of the Fedora
      Packaging Guidelines' second best choice.  Now we're using
      the choice they recommend most highly, without changes.

    o Removed unnecessary resources from vstudio/wforms example.

    o Minor URL fix in refman


2.2.2, 2007.04.13 (r1526) The "Nervousmaking Friday the 13th" release

    o More small fixes to embedded null handling in Query.

    o Fixed a bug in single-parameter template query handling.

    o Added tquery example, to demonstrate proper use of template
      queries.  Previously, resetdb was the only exemplar, and
      it wasn't really suited for that.  This example also tests
      the previous item.

    o Added examples/vstudio/mfc, allowing us to improve the way
      we demonstrate Unicode handling.  Old way wasn't realistic.
      On *ix, people will depend on the terminal code to handle
      UTF-8.  On Windows, users are almost certain to be writing
      a GUI program, which requires different Unicode handling
      than the old examples showed.

    o Removed explicit Unicode conversion stuff from command line
      examples, and reworked the Unicode chapter in the user
      manual.
    
    o Added examples/vstudio/wforms to show integration with
      C++/CLI and Windows Forms.  Documented this in README.vc.

    o Rewrote load_file and cgi_image examples to be more
      useful, renaming them to load_jpeg and cgi_jpeg along
      the way.  Also, resetdb now creates a second table in the
      sample database for these two examples' use.  Also, added
      examples/logo.jpg to the distribution as sample data for
      these examples.

    o Limited the ostream base class casting stuff in Query to
      VC++ 2003, which is the only platform that really needed it.
      VC++ 2005 emits a warning with that hack in place, and on
      other platforms it's just replicating work that the compiler
      does already.

    o Added library version information to main library target
      so that systems that version shared libraries work as
      expected.  Thanks for this patch go to Jack Eidsness.

    o Merged much of the diffs between Remi Collet's RPM spec file
      into the official one.

    o Reorganized the doc subdir a bit.  Generated HTML is now all
      under doc/html instead of scattered under other subdirs,
      and renamed doc/README.mysql++ to doc/README.manuals.

    o Improvements to top-level manual building make targets:
      manuals now only rebuild at need, it's easier to request
      a rebuild of all manuals, and we force a rebuild attempt
      before building the distribution tarball so we don't ship
      outdated manuals.

    o Added ability to run examples under gdb using exrun,
      using same mechanism as we currently have for valgrind.
      Thanks for this patch go to Michael Hanselmann.

    o Added "Important Underlying C API Limitations" chapter to the
      user manual, to cover problems we keep seeing on the
      mailing list that are the result of ignorance of the way
      libmysqlclient behaves, not bugs MySQL++ is really in a
      position to fix.


2.2.1, 2007.02.28 (r1433)

	* sqlplus.spec.in (Packager): Created new spec.in file to work
    o Fixed the new localtime() alternative selection code
      for VS2003 and various uses of STLport.

	with autoconf/automake and libtool for easier releases of
    o No longer inserting a null character into the query stream
      on calling one of the preview() functions.  This was harmless
      in v2.1, which used C strings more extensively, but began
      causing problems in v2.2 due to its wider use of C++ strings.

	RPMs. (Yes, I am a Linux bigot and I think the world should
    o Fixed a bug in the Connection copy ctor where it didn't
      completely initialize the object.

	revolve around RPMs).
    o Optimized Query::preview_char() a bit.  Patch by Jonathan
      Wakely.

    o Reordered directory list used by autconf when locating the
      MySQL C API library.  The list is now ordered with the
      most likely locations for the library first, so we're less
      distracted by incorrect libraries.  This fixes a specific
      build error under RHEL4 with recent versions of MySQL 5.0.


2.2.0, 2007.01.23 (r1417)

    o ColData, const_string, and SQLString can now be constructed
      with an explicit length parameter.  Furthermore, Query
      class's execute(), store() and use() call chains terminate
      in a version taking an explicit length parameter, instead
      of one taking a simple C string.  Together, this means
      that it's now easier to handle data from the SQL server
      containing nulls.  The library is almost certainly not yet
      capable of handling embedded nulls in all cases, but this
      is a big first step towards that.

    o Can now construct a DateTime object from a time_t, and
      convert a DateTime back to a time_t.  Patch by Korolyov Ilya.

    o Changed the way we're handling exported functions in the
      Windows DLL case so that it works more reliably under MinGW.

    o Added proper copy semantics to Connection, so that you get a
      new connection with the same parameters, not just a bitwise
      copy of the object.

    o Using an explicitly thread-safe variant of localtime() for
      time conversions where one is available.

    o Removed ListInsert template from myset.h.  This wasn't used
      within the library, and was never documented, so I'm betting
      that no one actually uses it.

    o Result::copy() was not copying the exception flag in
      all cases.  Fix by Steven Van Ingelgem.

    o Added exrun shell script and exrun.bat files to distribution,
      to avoid linkage errors when running the examples while
      you still have an older version of MySQL++ installed.

    o Renamed MYSQLPP_LIB_VERSION to MYSQLPP_HEADER_VERSION, as
      what it really encodes is the version number in the mysql++.h
      file you're using, not the actual library version number.

    o Added mysqlpp::get_library_version(), which returns the
      library version number at build time.  Between this and
      the header version constant, you can check that you're not
      mixing MySQL++ header and library versions.

    o resetdb example uses these new version number affordances to
      double-check that you're not mixing libraries and headers
      from different versions.  This happens easily unless you
      take care of it (such as by using exrun) when you have one
      version of MySQL++ installed and you're trying to build and
      test a new version without blowing away the old one first
      or overwriting it.

    o No longer using recursive Makefiles on Unixy platforms
      or split lib + examples project files on VC++.  Everything is
      handled by a single top-level Makefile or project file, which
      is simpler for the end user, and makes better dependency
      management possible.

    o When looking for the MySQL C library on systems using
      autoconf, looking in .../lib64 wherever we are also looking
      in .../lib.

    o RPM build process no longer depends on Bakefile.  It means
      you have to build the examples when building an RPM even
      though they're never used within the RPM, but it's a better
      tradeoff in my opinion.

    o Updated include and library paths on Windows to reflect
      changes in the most recent MySQL installers.

    o Merged lib/defs.h and lib/platform.h into new file,
      lib/common.h.  Just cleans up the library internals.

    o Fixed build errors on Windows due to recent changes in MySQL.

    o Fixed a few memory leaks and double-deletes in Query class.

    o Fixed compatibility with STLPort's string implementation.
      Patch by dengxy at cse.buaa.edu.cn.

    o Fixed a compatibility problem between Set<> template and
      SSQLS.  Patch by Korolyov Ilya.

    o Fixed build bug in SQLQueryParms due to a character
      signedness issue on PowerPC with GCC.  Patch by Michael
      Hanselmann.

    o ~Transaction() can no longer throw exceptions.  It'll just
      quietly eat them, to avoid program termination.  Fix
      suggested by Alex Burton.

    o Fixed thread safety testing in autoconf case, accidentally
      broken during v2.1.0 development cycle.

    o Using Doxygen 1.5.1 to generate documentation.


	
2.1.1, 2006.04.04 (r1289)

	* configure.in: Reworked this file to work with spec.in and
    o MinGW and Cygwin will now build and link to mysqlpp DLLs.

	support libtool type versioning.
    o Fixed bug in Query, causing it to initialize the "throw
      exceptions" flag incorrectly.  Thanks for this patch go to
      Joel Fielder.

    o Added -v flag for custom.pl script, which turns off the
      multiply-defined static variable fix.  Needed for VS 2003,
      which doesn't support variadic macros.  Also, added
      a diagnostic to detect the need for the -v flag, and
      suppressed the test for this feature in examples/util.cpp.


2.1.0, 2006.03.24 (r1269)

    o Converted automake and makemake files to their equivalents in
      Bakefile format.

    o Added the Transaction class, which makes it easy to use
      transaction sets in MySQL++.

    o Added xaction example to test new Transaction class.

    o Resetdb example now creates its example table using the
      InnoDB storage engine, in order to test the new transaction
      support.  Resetdb also declares the table as using UTF-8
      text; this doesn't change anything, but it does correctly
      document what we're doing.

    o Added sql_types.h header, containing C++ typedefs
      corresponding to each MySQL column type.  Using those new
      types in the type_info module, and in the SSQLS examples.

    o Replaced the way we were handling the template query
      version of Query member functions, to allow an arbitrary
      number of template query parameters.  By default, we
      now support 25 parameters, up from the old limit of 12.
      It's now possible to change just one number, run a script,
      and have a new limit.

    o Connection class does a better job of returning error
      messages if you call certain member functions that depend
      on a connection to the server before the connection is
      established.

    o Updated libmysqlclient.def for newer versions of MySQL.  (Fixes
      build errors having to do with mysql_more_results() and
      mysql_next_result().

    o Replaced final use of strcpy() with strncpy().

    o custom.pl now runs without complaint in strict mode, with
      warnings turned on.  Thanks for this patch go to "Waba".

    o Fixed a bug in custom.pl where incorrect code would be
      generated for some SSQLS set() methods.  Thanks for this
      patch go to "Waba".

    o SSQLS structures now support long and unsigned long fields.
      Thanks for this patch go to "Waba".

    o It's now possible to put SSQLS definitions in a header
      file used by multiple modules in a program without
      getting multiple static member definition errors.  See the
      documentation for details.  Thanks for this patch go to
      Viktor Stark.

    o Moved the definition of the 'stock' SSQLS out of the
      custom*.cpp example files and into a new stock.h file.
      Also, #including that file in the util module to test out
      the new SSQLS multiple static definition fix.

    o Using all of the digits of precision guaranteed by the
      IEEE 754 spec when stringizing floating point numbers
      to build queries.  Previously, we would use the platform
      default, which can be as few as 6 digits.

    o Removed lib/compare.h.  Not used within the library, never
      documented, and nobody seems to want to defend it.


2.0.7, 2005.11.23 (r1147)

    o Added explicit mysqlpp namespace qualifiers to generated code in
      custom*.h so you can use SSQLS in places where it doesn't make
      sense to say "using namespace mysqlpp" before the declaration.
      Also updated some of the examples to not have this "using"
      declaration to make it clear to users that it isn't needed, if you
      want to use explicit namespace qualifiers as well.  Thanks for
      this patch to Chris Frey.

    o Removed an apparently useless unlock() call from ResUse; there is
      no nearby lock() call, so if this unlock() is in fact necessary,
      it shouldn't be here anyway, because the two calls should be
      nearby each other.  Thanks for this patch to Chris Frey.

    o Fixed Query ostream initialization bug affecting SunPro CC (at
      least).  While this bug violates the Standard, it doesn't affect
      many real compilers because they don't enforce this rule.  Fixed
      by Chris Frey.

    o Previously, we only used the C99 style "long long" support when
      building under GNU CC.  This is now the default.  This should
      allow the code to work under SunPro CC.

    o Added another dynamic cast needed for proper Query ostream
      subclass overloading under VC++.  (7.1 at least...)

    o Detecting whether MySQL is built with SSL support on platforms
      using autotools.  Needed on some old Sun systems, for instance.
      Thanks for this patch to Ovidiu Bivolaru.

    o Fixed a potential memory bug in ColData's conversion to SQL null.

    o Many minor packaging tweaks.  (README clarifications, file
      permission fixes, better adherence to GNU packaging standards,
      etc.)

    
2.0.6, 2005.09.28 (r1123)

	
    o Fixed makemake.bat so it works on cmd.exe, not just 4NT.

1999-10-15 Sinisa Milivojevic <sinisa@cytanet.com.cy>
    o Documentation fixes.


2.0.5, 2005.09.13 (r1114)

    o Visual C++ build now requires GNU make.  It is tested to work
      with either the Cygwin or the MinGW versions.  The previous
      version of MySQL++ used nmake.  This change enabled the
      following features:

        o Debug and Release versions are both built into
          separate subdirectories.

        o Dependency tracking for release version works
          correctly now.  (Previously dependencies worked
          only for debug version.)

        o 'make clean' removes release version binaries
          in addition to debug versions.

    o MinGW makemake support updated to support new release/debug
      subdirectory system.  This is probationary support, since
      this code currently can't be built as a DLL.  As a result,
      it is no more useful than the Cygwin version, for licensing
      reasons.

    o Several fixes to allow building on Solaris 8.  These fixes may
      also help on other SVR4-derived systems.

    o Removed Borland C++ makemake support, because this version
      of the library does not work completely, and there seems
      to be almost no user interest in fixing it.
      
    o Clarified "Handling SQL Nulls" section of user manual's
      Tutorial chapter.


2.0.4, 2005.08.29 (r1076)

    o Made mysql_shutdown() second parameter autoconf check less
      sensitive to compiler pedantry.

    o VC++ library Makefile is now smart enough to re-create the
      import library, if it is deleted while leaving the DLL alone.

    o Added libmysqlclient.def to tarball.

    o Reworked most of the top-level README* files.

    o Renamed LGPL file to LICENSE.


2.0.3, 2005.08.25 (r1060)

    o Visual C++ makemake system updated to build both debug and
      release versions of library DLL.

    o Fixed bug in simple1 example that caused crashes on Windows.

    o Doing UTF-8 to ANSI text translation in simple examples now.

    o Previous two releases built libmysqlpp with wrong soname on
      autotools-based systems.  Fixed.


2.0.2, 2005.08.18 (r1050)

    o Fixes to makemake system for cmd.exe.

    o Fixed the case where the system's C++ library includes an slist
      implementation in namespace std.


2.0.1, 2005.08.17 (r1046)

    o Added new simple1 example, showing how to retrieve just one
      column from a table.  Old simple1 is now called simple2, and
      simple2 is likewise shifted to simple3.

    o Added custom6 example, showing how to do the same thing with
      SSQLS.

    o Updated user manual to cover new examples.

    o Was accidentally shipping Subversion crap with tarball.  Fixed.


2.0.0, 2005.08.16 (r1031) The "Excess Hair Removal" release

    THIS IS NOT A DROP-IN REPLACEMENT FOR MySQL++ v1.7!

    At minimum, you will have to recompile your program against
    this library.  You may also have to make code changes.
    Please see the "Incompatible Library Changes" chapter of
    the user manual for a guide to migrating your code to this
    new version:

    http://tangentsoft.net/mysql++/doc/userman/html/breakages.html

    o The library's shared object file name (soname) scheme has
      changed.  (This mainly affects POSIX systems.)
      
      The soname for the last 1.7.x releases of MySQL++ was
      libmysqlpp.so.4, meaning the fourth version of the library's
      application binary interface (ABI).  (The first ABI version
      in this scheme was that provided by 1.7.9.)  MySQL++
      2.0.0's soname is libmysqlpp.so.2.0.0.  Since the dynamic
      linker setup on some systems will create a symlink to
      that file called libmysqlpp.so.2, it's possible that this
      library could be confused with that for MySQL++ 1.7.19
      through .21, which also used this number.  Do not install
      this library on a system which still has binaries linked
      against that version of the library!

      The new scheme is {ABI}.{feature}.{bug fix}.  That is,
      the first number changes whenever we break the library's
      binary interface; the second changes when adding features
      that do not break the ABI; and the last changes when the
      release contains only internal bug fixes.  This means
      that we will probably end up with MySQL++ 3.0 and 4.0 at
      some point, so there will be further soname conflicts.
      Hopefully we can put these ABI changes off long enough
      to avoid any real problems.

    o autoconf now installs headers into $prefix/include/mysql++,
      instead of $prefix/include.  If you were using the
      --includedir configure script option to get this behavior
      before, you no longer need it.

    o Linux binary RPMs will henceforth include only the
      libmysqlpp.so.X.Y.Z file, and create any short names
      required, to allow multiple versions to be installed at
      once.  Currently, you cannot install two MySQL++ library
      RPMs at once, because they both have /usr/lib/libmysqlpp.so.X,
      for instance.

    o Replaced the Visual C++ and Borland C++ project files with
      a new "makemake" system, which creates Makefiles specific
      to a particular toolchain.  This new mechanism also supports
      MinGW and generic GCC-on-*ix.  This was done partly to reduce
      the number of places we have to change when changing the
      file names in MySQL++ or adding new ones, and partly so we're
      not tied to one particular version of each of these tools.

    o VC++ Makefiles create a DLL version of the library only
      now, so there's no excuse for LGPL violations now.
      This same mechanism should make DLL builds under other
      Windows compilers easy.

    o Added Connection::enable_ssl(), which enables encrypted
      connections to the database server using SSL.

    o Connection::create_db() and drop_db() now return true on
      success, not false.

    o Connection::create_db() and drop_db() use Query::exec()
      now, for efficiency, rather than Query::execute().

    o Removed Connection::infoo().  Apparently just there to
      save you from a typo when calling the info() method, since
      it was a mere alias.

    o Renamed Connection::real_connect() to connect(), gave
      several more of its parameters defaults, and removed old
      connect() function.  Then changed user manual and examples
      to use new APIs.

    o Replaced Connection::read_option() with new set_option()
      mechanism.  The name change matches the method's purpose
      better.  Functional changes are that it returns true on
      success instead of 0, it supports a broader set of options
      than read_option() did, and it enforces the correct option
      argument type.

    o You can now call Connection::set_option() before the
      connection is established, which will simply queue the option
      request up until the connection comes up.  If you use this
      feature, you should use exceptions, because that's the only
      way an option setting failure can be signalled in this case.

    o Removed query-building functions (exec*(), store*(),
      use()) from class Connection, and moved all the implementation
      code to class Query.  Query no longer delegates the final
      step of sending the query to the database server to
      Connection().

    o Added Connection::enable_ssl(), for turning on SSL support on
      a connection.

    o Extracted exception disabling mechanism out of the many
      classes that had the feature into a new OptionalExceptions
      base class, which all classes having this feature now
      derive from.  Also, removed all per-method exception
      handling flags.  Finally, added NoExceptions class.  With
      all of these changes, there is now a common way to disable
      exceptions with fine granularity on all objects that
      support the feature.

    o All custom MySQL++ exceptions now derive from the new
      Exceptions class.  This regularizes the exception interface
      and allows you to use a single catch() block if you want.

    o The "throw exceptions" flag is passed from parent to child
      in all situations now.  (Or if not, please report it as
      a bug.) This fulfills a promise made in the v1.7.9 user
      manual, with the cost being that some programs will see
      new exceptions thrown that they're not expecting.

    o Added a bunch of new exception types: BadOption,
      ConnectionFailed, DBSelectionFailed, EndOfResults,
      EndOfResultSets, LockFailed, and ObjectNotInitialized.
      Some of these replace the use of BadQuery, which in v1.7.x
      was a kind of generic exception, thrown when something more
      specific wasn't available.  Beware, this means that programs
      may start crashing after recompiling them under v2.0 due to
      uncaught exceptions, if they were only trying to catch BadQuery.

      There are additional instances where the library will
      throw new exceptions.  One is when calling a method that
      forces the internals to use an out-of-bounds index on a
      vector; previously, this would just make the program
      likely to crash.  Another is that the library uses the
      BadFieldName exception -- created in v1.7.30 -- in more
      apropos situations.

    o Renamed SQLQueryNEParms to BadParamCount, to match naming
      style of other concrete exception types.

    o Extracted lock()/unlock() functions from Connection and
      Query classes into a new Lockable interface class.  Locking
      is implemented in terms of a different class hierarchy, Lock,
      which allows multiple locking strategies with a single ABI.

    o Removed ResUse::eof().  It's based on a deprecated MySQL
      C API feature, and it isn't needed anyway.

    o Removed arrow operator (->) for iterator returned by Fields,
      Result and Row containers.  It was inherently buggy, because
      a correct arrow operator must return the address of an
      object, but the underlying element access functions in these
      classes (e.g. at()) return objects by value, of necessity.
      Therefore, this operator could only return the address of
      a temporary, which cannot be safely dereferenced.

    o Returned Row subscripting to something more like the
      v1.7.9 scheme: there are two operator[] overloads, one for an
      integer (field by index) and another for const char* (field
      by name).  lookup_by_name() has been removed.  Because row[0]
      is ambiguous again, added Row::at() (by analogy with STL
      sequence containers), which always works.

    o Collapsed two of the Row::value_list*() overloads into
      two other similar functions using default parameters.
      This changes the API, but the removed functions aren't
      used within the library, and I doubt they are used outside,
      either.

    o Merged RowTemplate into Row.

    o Merged SQLQuery class into Query class.

    o Query is now derived from std::ostream instead of
      std::stringstream, and we manage our own internal string
      buffer.

    o Moved SQLParseElement and SQLQueryParms into their own
      module, qparms.

    o Added multiple result set handling to Query.  MySQL 4.1
      and higher allow you to give multiple SQL statements in a
      single "store" call, which requires extensions to MySQL++
      so you can iterate through the multiple result sets.  Also,
      stored procedures in MySQL 5.0 reportedly return multiple
      result sets.  Thanks for the initial patch go to Arnon Jalon;
      I reworked it quite a bit.

    o Query::storein*() now supports more varieties of the
      nonstandard slist comtainer.  (Singly-linked version of
      STL std::list.)

    o Template query mechanism and user manual had several
      mismatches.  Made manual match actual behavior, or
      made library match documented behavior, as apropriate.
      Initial patch by Jürgen MF Gleiss, with corrections and
      enhancements by Warren Young.

    o Collapsed mysql_* date and time base classes' methods and
      data into the subclasses.  Also, DateTime no longer derives
      from Date and Time; you could get away with that in the
      old hierarchy, but now it creates an inheritance diamond,
      and allows unsupported concepts like comparing a Time to
      a DateTime.

    o Removed "field name" form of Row::field_list().  It was
      pretty much redundant -- if you have the field names, why
      do you need a list of field names?

    o ColData can convert itself to bool now.  Thanks for this
      patch go to Byrial Jensen.

    o Removed simp_list_b type; wasn't being used, and doesn't
      look to be useful for end-user code.

    o Several methods that used to take objects by value now
      do so by const reference, for efficiency.

    o Several variable and function renamings so that MySQL++
      isn't needlessly tied to MySQL.  Even if we never make
      the library work with other database servers, there's
      little point in tying this library to MySQL blindly.

    o Renamed all private data members of MySQL++ classes to
      have trailing underscores.

    o 'private' section follows 'public' section in all classes
      now.

    o Removed mysql++.hh and sqlplus.hh backwards-compatibility
      headers.

    o Added copy ctors to Date/Time classes so that they will
      work in SSQLS under GCC 4.0.0.  Without these, the compiler
      couldn't make the conversion from raw MySQL row data.

    o Fixed a bunch of GCC 4.0 pedantic warnings: added virtual
      dtors to all base classes, calling base class ctors from leaf
      classes, etc.

    o All warnings fixed under VC++ at warning level 3.  (Mostly
      harmless signedness and integer conversion stuff.)

    o Updated LGPL license/copyright comments at the top of
      several files to use FSF's new physical address.

    o Relicensed user manual under a close variant of the Linux
      Documentation Project License, as it's designed for
      documentation, which the LGPL is not.  Permission for this
      received from Kevin Atkinson and MySQL AB.

    o Added ABI and API breakages chapter to user manual.  It
      is basically a subset of this ChangeLog, with only the
      information an end-user must know when migrating between
      versions.

    o Reworked user manual's DocBook code quite a bit after
      reading Bob Stayton's book "DocBook XSL" 3/e.  Better handling
      of stylesheets, taking advantage of some superior DocBook
      features, prettier output (especially the HTML version), etc.

    o Rewrote doc/userman/README to make it clearer how to get
      started contributing to the user manual.  It's essentially a
      "getting started with DocBook" guide now!

    o Lots of small text improvements to user and reference
      manuals.  Aside from the obvious tracking of library changes,
      made a bunch of minor style and clarity improvements.

    o Added CSS stylesheets for userman and refman to
      make the HTML versions of each a) not ugly; and b) match
      tangentsoft.net.  (Yes, some may say that these are incompatible
      goals....)

    o Standardized exception handling code in the examples that
      use it.

    o Fixed a potential memory leak due to exceptions thrown from
      ResUse.  Thanks for this patch go to Chris Frey.

    o Using new "no exceptions" feature of library in simple1
      example, so it is now truly simple.

    o simple1 example no longer depends as much on util module, so
      that all of the important code is in one place.  Makes
      learning MySQL++ a little less intimidating.

    o Added new simple2 and usequery examples, to demonstrate
      the proper way to handle a "use" query, with exceptions
      disabled, and not, respectively.  Added them to the user
      manual, in the appropriate place.

    o Refactored the "print stock table" example functions
      again, to make code using them clearer.

    o UTF-8 to UCS-2 handling in examples is now automatic on
      Windows.

    o Removed debug code from Windows Unicode output examples
      that slipped into previous release.

    o resetdb example is now clearer, and more robust in the
      face of database errors.

    o Simplified connect_to_db() in examples' util module.

    o Added sample autoconf macro for finding MySQL++ libraries, for
      people to use in their own autotools-based projects.

    o Lots and lots of minor cleanups not worth mentioning
      individually...


1.7.40, 2005.05.26 (r719)

    o Multiple item form of insert() now works if you're using the
      SQLQuery class, or its derivative, Query.  Thanks to Mark
      Meredino for this patch.

    o Fixed a bug in const_string::compare(), in which MySQL++
      would walk off the end of the shorter of the two strings.
      All was well if the two were the same length.

    o ResUse::operator=() now fully updates the object, so it's more
      like the behavior of the full ctor.

    o All source files now contain a license and copyright statement
      somewhere within them.

    o Optimized mysql++.h a bit: it now #includes only the minimum set
      of files required, and there is now an idempotency guard.
      This improves compile times a smidge, but mainly it was
      done to clean up the generated #include file graph in the
      reference manual.  Before, it was a frightful tangle because
      we #included everything except custom*.h.

           
    o Constness fix in MySQL++ date/time classes to avoid compiler
      warnings with SSQLS.  Thanks to Wolfram Arnold for this patch.

* Changed version to 1.2					 
    o Fixed some compiler warnings in custom*.h.  Thanks to Chris Frey
      for this patch.

* First offical release. Version 1.0 and 1.1 were releases by Sinisa
    o Added "Submitting Patches" and "Maintaining a Private CVS
      Repository" sections to the HACKERS file.  Thanks to Chris
      Frey for the source material for these sections.  The HACKERS
      file was improved in several other ways at the same time.

  before I (Kevin Atkinson) made him the offical maintainer,
    o PDF version of user manual no longer has links to the reference
      manual.  They were ugly, and they were broken anyway due to the
      way we move the PDFs after generating them.  If you want
      interlinked manuals, use the HTML version.

* Many manual fixes.
    o PDF version of user manual now has hard page breaks between
      chapters.

* Changed README and Changelog
    o Removed complic1 example.  Wasn't pulling its own weight.
      Everything it is supposed to demonstrate is shown in other
      examples already.

* Changed source to be compilable by gcc 2.95.xx, tribute to Kevin
    o Refactored print_stock_table() in examples/util module to be
      four functions, and made all the examples use various of
      these functions where appropriate.  Before, several of
      the examples had one-off stock table printing code because
      print_stock_table() wasn't exactly the right thing, for one
      reason or another.  One practical problem with this is that
      some of the examples missed out on the recent Unicode updates;
      now such a change affects all examples the same way.

  Atkinson <kevinatk@home.com>
    o Since so many of the examples rely on the util module, the user
      manual now covers it.  The simple1 example in the user manual
      didn't make much sense before, in particular, because it's
      really just a driver for the util module.

* Added methods in Connection class which are necessary for
    o Added custom5 example.  It shows how to use the equal_list()
      functionality of SSQLS.  Thanks to Chris Frey for the original
      version of this program.  (I simplified it quite a bit after
      accepting it.)

  fullfilling administrative functions with MySQL
    o New user manual now covers the value_list(), equal_list() and
      field_list() stuff that the old manual covered but which was
      left out in previous versions of the new manaul.  Most of the
      examples are the same, but the prose is almost completely new.
      This new section includes the custom5 example.

* Added many bug fixes in code pertaining to missing class
    o Every declaration in MySQL++ is now documented in the reference
      manual, or explicitly treated as "internal only".

  initializers , as notified by Michael Rendell <michael@cs.mun.ca>
    o Improved docs for MySQL++'s mechanism to map between MySQL
      server types and C++ types.  Initial doc patch by Chris Frey,
      which I greatly reworked.

* Sinisa Milivojevic <sinisa@cytanet.com.cy> is now the offical
    o Improved a lot of existing reference manual documentation while
      adding the new stuff.

  maintainer.
    o Expanded greatly on the exception handling discussion in the user
      manual.

    o Added all-new "Quoting and Escaping" section to the user
      manual's Tutorial chapter.  Moved some existing comments on
      quoting and escaping around and added some new ones to other
      sections as a result.

    o Added all-new "Handling SQL Nulls" section to the user manual's
      Tutorial chapter.

1999-08-02  Sinisa Milivojevic <sinisa@cytanet.com.cy>
    o Many improvements to the Overview section of the user manual.

    o Row::operator[] reference now explains the right and wrong way to
      use the values it returns.  This is in response to a mailing list
      post where someone was incorrectly using this feature and getting
      a bunch of dangling pointers.

    o Updated Doxyfile so 1.3.19.1 parses it without warnings.  Still
      works with versions back to 1.2.18, at least.  (These are
      the versions shipped with Fedora Core 3 and Red Hat Linux 9,
      respectively.)

    o Using a superior method to make Doxygen ignore certain sections
      of the source code.  Between this change and the fact that
      everything not so ignored is documented, Doxygen no longer
      generates any warnings.

    o Lots of code style updates.  Everything should now be consistently
      formatted.


1.7.35, 2005.05.05 (r601) The "Cinco de Mayo" release

    o Added a "how to use Unicode with MySQL++" chapter to the user
      manual.  (Too bad "Cinco de Mayo" doesn't have any accented
      characters.  That would be just _too_ precious.)

    o VC++ examples now use the Unicode Win32 APIs, so they can display
      Unicode data from MySQL++.

    o Added an optional conversion function to examples/util.cpp to
      handle the conversion from UTF-8 to UCS-2 on Win32.

    o Moved "brief history of MySQL++" from intro section of refman to
      intro section of userman.

    o Lots of small bits of documentation polishing.
    
    o Made some minor constness fixes.  Thanks to Erwin van Eijk
      for this patch.

    o Made some warning fixes for GCC 4.0.  Not all warnings are
      fixed, because some of the needed changes would break the ABI.
      Thanks to Chris Frey for this patch.

    o Added lib/Doxyfile to distribution.
    

1.7.34, 2005.04.30 (r573)

    o Added a multiple-insert method for Query, which lets you insert
      a range of records from an STL container (or the whole thing,
      if you like) in a single SQL query.  This is faster, and it
      reduces coding errors due to less repetition.  Thanks to Mark
      Meredino for the patch.

    o Reference and user manual now get rebuilt automatically when
      required.  (E.g. on 'make dist', or explicitly now through 'make
      docs'.)

    o Made it easier to change the maximum number of SSQLS data members
      in generated custom-macros.h file.  It used to be hard-coded in
      several places in lib/custom.pl; now it's a variable at the top of
      the file.

    o Changed default SSQLS data member limit to 25, which is what it
      has been documented as for a long time now.  It was actually 26
      within custom.pl.

    o Fixed a regression in previous version.

    o Trimmed some fat from the distribution packages.

    o Some more small doucmentation improvements.


1.7.33, 2005.04.29 (r555)

    o Worked around an overloaded operator lookup bug in VC++ 7.1
      that caused SSQLS insert, replace and update queries to get
      mangled.  (Symptom was that custom2 and custom3 examples didn't
      work right.)  Thanks to Mark Meredino for digging up the
      following, which explains the problem and gives the solution:

      http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15

    o Some VC++ warning fixes.

    o Major documentation improvements:
    
        o Using DocBook for user manual and Doxygen for reference
          manual.  The former now references the latter where
          useful.

        o Split out HACKERS and CREDITS files from main README,
          and improved remaining bits of README.

        o Moved the text from the old v1.7.9 LaTeX-based
          documentation over into the new systems, and reworked
          it to more closely resemble English.

        o Added a lot of new material to documentation, and
          simplified a lot of what already existed.

        o Documentation is now being built in HTML and PDF forms.

    o ebuild file updated to take advantage of recent configure script
      features.  Thanks to Chris Frey for this patch.



1.7.32, 2005.03.10 (r479)

    o Example building may now be skipped with --disable-examples
      configure script flag.

    o Changed stock items added in resetdb.  One is now UTF-8 encoded,
      to show that basic use of Unicode with MySQL++ is easy, yet not
      foolproof.  (See formatting of table on systems where cout isn't
      UTF-8 aware!)  Other stock items now follow a theme, for your
      amusement.  :)

    o custom3 example now changes UTF-8 item's name to the 7-bit ASCII
      equivalent.  Previously, this example would fix a spelling error
      in the table.

    o resetdb example now says 'why' when it is unable to create the
      sample database.

    o Small formatting change to print_stock_table(), used by several
      examples.

    o Was issuing a VC++-specific warning-disable pragma when built by
      any Windows compiler.  Fixed.
    

1.7.31, 2005.03.05 (r462) The "Inevitable Point-one Followup" release

    o Check for threads support must now be explicitly requested via
      configure script's new --enable-thread-check flag.

    o Fix for contacting MySQL server on a nonstandard port number.
      Thanks to Chris Frey for this patch.

    o Example programs using standard command line format now accept a
      fourth optional parameter, a port number for the server.  Thanks
      to Chris Frey for this patch.

    o One more g++ 3.4 pedantic warning fix by Chris Frey.

    o Exception handling in resetdb is no longer nested, because you'd
      get a segfault on some systems when an exception was thrown from
      one of the inner try blocks.

    o Improvements to Connection class's handling of locking mechanism.
      Concept based on patches by Rongjun Mu.

    o Implemented the declared-but-never-defined Query::lock().  Thanks
      to Rongjun Mu for this patch.
    
    o Cleaned up some unclear if/else blocks in connection.cpp by
      adding explicit braces, correct indenting and putting normal
      code path in the if side instead of the else.


1.7.30, 2005.02.28 (r443) The "Power of Round Numbers" release

    o bootstrap script now accepts a 'pedantic' argument, which sets a
      bunch of CFLAGS that make g++ very picky about the code it
      accepts without warnings.
      
    o Fixed a bunch of things that generated warnings with g++ in
      pedantic mode. Only two warnings remain, having to do with
      floating point comparisons.  (See Wishlist for plans on how to
      deal with these.)  Thanks to Chris Frey for this patch.

    o Split long tests out of configure.in into M4 files in new config
      subdir.  This makes configure.in easier to read.

    o Added preliminary thread support.  Currently, this just means that
      we detect the required compiler and linker thread flags, and link
      against the proper thread-safe libraries.  THERE MAY BE
      UN-THREAD-SAFE CODE IN MYSQL++ STILL!

    o Standard C++ exceptions are the default now.  Old pre-Standard
      exception stuff removed.

    o Row::lookup_by_name() will throw the new BadFieldName exception if
      you pass a bad field name.  Thanks for this patch to Chris Frey.

    o Row::operator[] will throw a Standard C++ out of bounds exception
      by way of std::vector::at() if you pass it a bad index.  Thanks
      for this patch to Chris Frey.

    o Setting Connection::is_connected flag to false on close().
      Previously, is_connected() would continue to return true after
      close() was called.

    o All number-to-string conversion ctors in SQLString class now use
      ostringstream to do the conversion.  Previously, we used
      snprintf(), which isn't available on all systems.  Also, we used a
      C99 format specifier for the "long long" conversion, which is also
      not available on all systems.  This new ostringstream code should
      be platform-independent, finally.


1.7.28, 2005.02.04 (r403)

    o --with-mysql* flags to configure script now try the given
      directory explicitly, and only if that fails do they try
      variations, like tacking '/lib' and such onto it to try and find
      the MySQL includes and libraries.  Thanks to Matthew Walton for
      the patch.

    o Finally removed sql_quote.h's dependence on custom.h, by moving
      the one definition it needed from custom.h to deps.h.  This will
      help portability to compilers that can't handle the SSQLS macros,
      by making that part of the library truly optional.


1.7.27, 2005.01.12 (r395)

    o configure check for libmysqlclient now halts configuration if the
      library isn't found.  Previously, it would just be flagged as
      missing, and MySQL++ would fail to build.

    o Added sql_string.cpp to VC++ and BCBuilder project files.

    o Removed Totte Karlsson's 'populate' example, which never made it
      into the distribution anyway.

    o Removed last vestiges of 'dummy.cpp'.

    o Renamed *.cc to *.cpp in BCBuilder project files.

    o Worked around a BCBuilder C++ syntax processing bug in row.h.


1.7.26, 2004.12.17 (r382)

    o Moved all of the SQLString definitions out of the header and into
      a new .cpp file, reformatted it all, and made the integer
      conversion functions use snprintf() or _snprintf() instead of
      sprintf().  Also, widened some of the buffers for 64-bit systems.

    o Using quoted #include form for internal library headers, to avoid
      some problems with file name clashes.  (The headers should still
      be installed in their own separate directory for best results,
      however.)  Thanks to Chris Frey and Evan Wies for the patch and
      the discussion that lead to it.

    o Removed unnecessary semicolons on namespace block closures.
      Thanks to Evan Wies for this patch.

    o Fixed namespace handling in the legacy headers mysql++.hh and
      sqlplus.hh.  Thanks to Chris Frey for this patch.

    o #including iostream instead of ostream in lib/null.h for
      broader C++ compatibility.  (This may allow MySQL++ to work on GCC
      2.95.2 again, but this is unconfirmed.)

    o Detecting proper mysql_shutdown() argument handling automatically
      in platform.h for the Windows compiler case instead of making the
      user edit the file.  Thanks to Evan Wies for this patch.
    
    o Fixed examples/Makefile.simple to use new *.cpp file naming.

    o Fix to Gentoo ebuild file's exception configure switch handling.
      Thanks to Chris Frey for this patch.

    o Rebuilding lib/custom*.h intelligently now, to avoid unnecessary
      recompiles after running bootstrap script.


1.7.25, 2004.12.09 (r360)

    o Yet more fixes to the --with-mysql-lib and --with-mysql-include
      flags.

    o Added DLLEXPORT stuff to platform.h, hopefully so that someone
      can figure out how to make VC++ make a DLL version of MySQL++.

    o Renamed *.cc to *.cpp.

    o Made 'set -> myset' change in VC++ project files.

    o Some style changes (mostly whitespace) in header files.


1.7.24, 2004.12.08 (r343)

    o Fixed the --with-mysql-lib and --with-mysql-include flags'
      behavior, and extended their search ability to handle one other
      common case.  (Fixed by Steve Roberts)

    o Fixes to put freestanding functions in namespace mysqlpp.  (They
      weren't in the namespace, while all the class member functions
      were.)  This required bumping the ABI version number to 4.
      
    o Renamed set module to myset, to avoid conflicts with Standard C++
      Library's set.h when MySQL++ headers were installed into one of
      the standard system include directories.

    o Renamed all the idempotency guards to make them consistent in
      style and unique to MySQL++.

    o Reformatted all of lib/*.cc.


1.7.23, 2004.11.20 (r333)

    o Query::reset() now empties the stored query string.  If you
      subsequently stored a longer query in the object, you'd overwrite
      the previous query, but otherwise the longer part of the previous
      one would stick out past the new query.

    o We now look to the NO_LONG_LONGS macro only to decide whether to
      fake 64-bit integer support using 32-bit integers.

    o 64-bit integer support under Visual C++ may be working now, using
      that platform's __int64_t type.  This has not been tested.

    o Removed 64-bit integer support for Codewarrior on Mac OS 9 and
      earlier.  OS X uses GCC, so it requires no special support.

    o Added MinGW detection in platform.h.
    
    o If you pass a flag (-X) to the examples that take the standard
      parameters (resetdb, simple1, etc.), it prints a usage message.
    
    o Better error handling in resetdb example, where errors are the
      most critical.  (If that one runs without errors, the others
      probably will, too, and you have to run that one first.)

    o resetdb now reports success, rather than succeeding silently.

    o Removed the code in sample1 example that duplicated util module's
      print_stock_table(), and called that function instead.

    o Moved the preview() calls in the example programs to before the
      query execution calls, because execution modifies the query.

    o All examples that take the standard command line parameters now 
      exit when connect_to_db() fails in one of the ways that don't
      throw an exception, rather than bulling onward until the next
      MySQL database call fails because the connection isn't up.

    o dbinfo example now takes the standard command line parameters.

    o Much better output formatting in dbinfo example.

    o Calling reset() where appropriate in the various example programs.
      Before, the programs may have worked, but not for the right
      reason.  This lead some people to believe that calling reset()
      was not necessary.

    o Fixed an incorrect use of row["string"] in complic1 example.

    o Lots of code style improvements to the examples.

    o Some VC++ type warnings squished.  Some remain.
    

1.7.22, 2004.11.17 (r302)

    o Applied patches by Zahroof Mohammed to allow it to build under GCC
      3.4.2.  Tested on MinGW and Fedora Core 3 systems.

    o Removed all the forward declarations in defs.h, and added
      forward declarations where necessary in individual header files.
      #including defs.h in fewer locations as a result.

    o Legacy headers sqlplus.hh and mysql++.hh now declare they are
      using namespace mysqlpp, to allow old code to compile against the
      new library without changes.

    o Removed query_reset parameter from several class Query member
      functions.  In the implementation, these parameters were always
      overridden!  No sense pretending that we pay attention to these
      parameters.  This changes the ABI version to 3.

    o #including custom.h in sql_query.h again...it's necessary on GCC
      3.4.
    
    o bootstrap script runs lib/config.pl after configure.  This is
      just a nicety for those running in 'maintainer mode'.


1.7.21, 2004.11.05 (r273)

    o Generating a main mysql++ RPM containing just the library files
      and basic documentation, and the -devel package containing
      everything else.

    o Devel package contains examples now, along with a new Makefile
      that uses the system include and library files, rather than the
      automake-based Makefile.am we currently have which uses the files
      in the mysql++ source directory.

    o Renamed sqlplusint subdirectory in the package to lib.

    o Removed the obsolete lib/README file.

    o lib/sql_query.h no longer #includes custom.h, simplifying
      build-time dependencies and shortening compile times.


1.7.20, 2004.11.03 (r258)

    o Collapsed all numbered *.hh headers into a single *.h file.  For
      example, the contents of row1.hh, row2.hh and row3.hh are now in
      row.h.

    o While doing the previous change, broke several circular
      dependencies.  (The numbered file scheme was probably partly done
      to avoid this problem.)  The practical upshot of most of these
      changes is that some functions are no longer inline.

    o Removed define_short.hh and everything associated with it.  The
      library now uses the short names exclusively (e.g. Row instead of
      MysqlRow).

* Changed version to 1.1
    o Put all definitions into namespace mysqlpp.  For most programs,
      simply adding a 'using namespace mysqlpp' near the top of the
      program will suffice to convert to this version.

* Added several bug fixes
    o Once again, the main include file was renamed, this time to
      mysql++.h.  Hopefully this is the last renaming!

* Fixed memory leak problems and variables overlapping problems.
    o mysql++.hh still exists.  It emits a compiler warning that the
      file is obsolete, then it #includes mysql++.h for you.

* Added automake and autoconf support by loic@net.fr
    o sqlplus.hh is back, being a copy of the new mysql++.hh.  Both of
      these files may go away at any time.  They exist simply to help
      people transition to the new file naming scheme.

* Added Makefile for manual
    o Renamed mysql++-windows.hh to platform.h, and added code to it to
      handle #inclusion of config.h on autotools-based systems
      intelligently.  This fixes the config.h error when building under
      Visual C++.

* Added support for cygwin
    o There is now only one place where conditional inclusion of
      winsock.h happens: platform.h.

* Added example sinisa_ex (let modesty prevail) which used to crash a 
    o Beautified the example programs.


  lot when memory allocation, memory leak and overlap problems were
  present. Smooth running of this example proves that all those bugs are
1.7.19, 2004.10.25 (r186)

	fixed
    o Fixed an infinite loop in the query mechanism resulting from the
      strstream change in the previous version.  There is an overloaded
      set of str() member functions that weren't a problem when query
      objects were based on strstream.
     
* Changed manual
    o Query mechanism had a bunch of const-incorrectness: there were
      several function parameters and functions that were const for
      the convenience of other parts of the code, but within these
      functions the constness was const_cast away!  This was evil
      and wrong; now there are fewer const promises, and only one is
      still quietly broken within the code.  (It's in the SQLQuery
      copy ctor implementation; it should be harmless.)

* Cheanged README
    o Removed operator=() in Query and SQLQuery classes.  It cannot take
      a const argument for the same reason we have to cast away const
      in the SQLQuery copy ctor.  It's tolerable to do this in the copy
      ctor, but intolerable in an operator.  Since the copy ctor is good
      enough for all code within the library and within my own code, I'm
      removing the operator.

* Many other smaller things
    o Above changes required bumping the ABI to version 2.

    o Visual C++ projects now look for MySQL build files in c:\mysql,
      since that's the default install location.  (Previously, it was
      c:\program files\mysql.)


1999-06-09  Michael Widenius  <monty@monty.pp.sci.fi>
1.7.18, 2004.10.01 (r177)

    o Changed all the strstream (and friends) stuff to stringstream type
      classes.  Let there be much rejoicing.

    o Query object now lets you use store() even when the SQL query
      cannot return a result, such as a DROP TABLE command.  This is
      useful for sending arbitrary SQL to the server.  Thanks to
      Jose Mortensen for the patch.

    o Quote fix in configure.in, thanks to David Sward.

    o Renamed undef_short file to undef_short.hh.

    o Gentoo ebuild file is actually being shipped with the tarball,
      instead of just sitting in my private CVS tree since 1.7.14 was
      current.  Ooops....


1.7.17, 2004.09.16 (r170)

    o Reverted one of the VC++ warning fix changes from 1.7.16 that
      caused crashes on Linux.

    o Added a configure test that conditionally adds the extra 'level'
      parameter to mysql_shutdown() that was added in MySQL 4.1.3 and
      5.0.1.


1.7.16, 2004.09.13 (r160)

    o Building VC++ version with DLL version of C runtime libraries, and
      at warning level 3 with no warnings emitted.

    o VC++ build no longer attempts to fake "long long" support.  See
      the Wishlist for further thoughts on this.


1.7.15, 2004.09.02 (r144)

    o Renamed Configure file to common.am, to avoid file name conflict
      with configure script on case-sensitive file systems.

    o Added ebuild file and ebuild target to top-level Makefile for
      Gentoo systems.  Thanks to Chris Frey for this.

    o Small efficiency improvements to BadQuery exception handling.
      Initial idea by Chris Frey, improvements by Warren Young.


1.7.14, 2004.08.26 (r130)

    o Builds with Visual C++ 7.1.

    o Fixed a bug in custom macro generation that caused problems with
      GCC 3.4.  (X_cus_value_list ctor definition was broken.)


1.7.13, 2004.08.23 (r92)

    o Removed USL CC support.  (System V stock system compiler.)  Use
      GCC on these platforms instead.

    o Added examples/README, explaining how to use the examples, and
      what they all do.

    o Most of the example programs now accept command line arguments for
      host name, user name and password, like resetdb does.

    o Renamed sinisa_ex example to dbinfo.

    o Several Standard C++ syntax fixes to quash errors emitted by
      GCC 3.4 and Borland C++ Builder 6.  Thanks to Steffen Schumacher
      and Totte Karlsson for their testing and help with these.

    o Added proper #includes for BCBuilder, plus project files for same.
      Thanks to Totte Karlsson for these.


1.7.12, 2004.08.19 (r63)

    o Many Standard C++ fixes, most from the GCC 3.4 patch by
      Rune Kleveland.

    o Added Wishlist file to distribution.

    o Fixed a problem in the bootstrap script that caused complaints
      from the autotools on some systems.

    o RPM building is working properly now.

    o Fixed the idempotency guard in datetime1.hh.


1.7.11, 2004.08.17 (r50)

    o Renamed mysql++, defs and define_short files, adding .hh to the
      end of each.  (They're header files!)  This shouldn't impact
      library users, since these are hopefully used internal to the
      library only.

    o Removed sqlplus.hh file.  Use mysql++.hh instead.
    
    o Added mysql++.spec, extracted from contributed 1.7.9 source RPM, 
      and updated it significantly.  Also, added an 'rpm' target to
      Makefile.am to automate the process of building RPMs.

    o Added bootstrap and LGPL files to distribution tarball.

    o Added pre-1.7.10 history to this file.

    o Removed .version file.  Apparently it's something required by old
      versions of libtool.


1.7.10, 2004.08.16 (r27)

    o Maintenance taken over by Warren Young (mysqlpp at etr dash usa
      dot com.) See http://lists.mysql.com/plusplus/3326 for details.

    o Applied many of the GCC 3.x patches submitted for 1.7.9 over
      the years.  This allows it to build on everything from 3.0 to
      3.3.3, at least.  Because so many patches are rolled up in one
      big jump, it's difficult to describe all the changes and where
      they came from.  Mostly they're Standard C++ fixes, as GCC
      has become more strict in the source code that it will accept.

    o MysqlRow used to overload operator[] for string types as well as
      integers so you could look up a field by its name, rather than by
      its index.  GCC 3.3 says this is illegal C++ due to ambiguities in
      resolving which overload should be used in various situations.
      operator[] is now overloaded only for one integer type, and a
      new member function lookup_by_name() was added to maintain the old
      by-field-name functionality.

    o Fixed another operator overloading problem in SSQLS macro
      generation with GCC 3.3.

    o The _table member of SSQLS-defined structures is now const char*,
      so you can assign to it from a const char* string.

    o Got autoconf/automake build system working with current versions
      of those tools again.  Removed the generated autotools files from
      CVS.

    o Renamed library file from libsqlplus to libmysqlpp.


1.7.9 (May 1 2001) Sinisa Milivojevic <sinisa@mysql.com>

    * Fixed a serious bug in Connection constructor when reading MySQL
    * options
    * Improved copy constructor and some other methods in Result /
    * ResUse
    * Many other minor improvements
    * Produced a complete manual with chapter 5 included
    * Updated documentation, including a Postscript format

1.7.8 (November 14 2000) Sinisa Milivojevic <sinisa@mysql.com>

    * Introduced a new, standard way of dealing with C++ exceptions.
    * MySQL++ now supports two different methods of tracing exceptions.
    * One is by the fixed type (the old one) and one is standard C++
    * type by the usage of what() method. A choice of methods has to be
    * done in building a library. If configure script is run with
    * -enable-exception option , then new method will be used. If no
    * option is provided, or -disable-exception is used, old MySQL++
    * exceptions will be enforced. This innovation is a contribution of
    * Mr. Ben Johnson <ben@blarg.net>
    * MySQL++ now automatically reads at connection all standard MySQL
    * configuration files
    * Fixed a bug in sql_query::parse to enable it to parse more then 99
    * char's
    * Added an optional client flag in connect, which will enable usage
    * of this option, e.g. for getting matched and not just affected
    * rows. This change does not require any changes in existing
    * programs
    * Fixed some smaller bugs
    * Added better handling of NULL's. Programmers will get a NULL
    * string in result set and should use is_null() method in ColData to
    * check if value is NULL
    * Further improved configuration
    * Updated documentation, including a Postscript format

1.7.6 (September 22 2000) Sinisa Milivojevic <sinisa@mysql.com>

    * This release contains some C++ coherency improvements and scripts
    * enhacements
    * result_id() is made available to programmers to fetch
    * LAST_INSERT_ID() value
    * Connection constroctur ambiguity resolved, thanks to marc@mit.edu
    * Improved cnnfigure for better finding out MySQL libraries and
    * includes
    * Updated documentation, including a Postscript format

1.7.5 (July 30 2000) Sinisa Milivojevic <sinisa@mysql.com>

    * This release has mainl bug fixes  and code improvements
    * A bug in FieldNames::init has been fixed, enabling a bug free
    * usage of this class with in what ever a mixture of cases that is
    * required
    * Changed behaviour of ResUse, Result and Row classes, so that they
    * could be re-used as much as necessary, without any memory leaks,
    * nor with any re-initializations necessary
    * Fixed all potential leaks that could have been caused by usage of
    * delete instead of delete[] after memory has been allocated with
    * new[]
    * Deleted all unused classes and macros. This led to a reduction of
    * library size to one half of the original size. This has
    * furthermore brought improvements in compilation speed
    * Moved all string manipulation from system libraries to
    * libmysqlclient, thus enabling uniformity of code and usage of 64
    * bit integers on all platforms, including Windows, without
    * reverting to conditional compilation. This changes now requires
    * usage of mysql 3.23 client libraries, as mandatory
    * Changed examples to reflect above changes
    * Configuration scripts have been largely changed and further
    * changes shall appear in consecutive sub-releases. This changes
    * have been done and shall be done by our MySQL developer Thimble
    * Smith <tim@mysql.com>
    * Changed README, TODO and text version of manual. Other versions of
    * manual have not been updated
    * Fixed .version ``bug''. This is only partially fixed and version
    * remains 1.7.0 due to some problems in current versions of libtool.
    * This shall be finally fixed in a near future
    * Several smaller fixes and improvements
    * Added build.sh script to point to the correct procedure of
    * building of this library. Edit it to add configure options of your
    * choice

1.7 (May17 2000) Sinisa Milivojevic <sinisa@mysql.com>

    * This is mainly a release dealing with bug fixes, consistency
    * improvements and easier configure on some platforms
    * A bug in fetch_row() method of ResUse class has been fixed. Beside
    * changes that existed in a distributed patch, some additional error
    * checking has been introduced
    * A bug in escape manipulator has been fixed that could cause an
    * error if all characters had to be escaped
    * An inconsistency in column indexing has been fixed. Before this
    * version, column names in row indexing with strings, i.e.
    * row[<string>] , has been case sensitive, which was inconsistent
    * with MySQL server handling of column names
    * An inconsistency in conversion from strings to integers or floats
    * has been fixed. In prior version a space found in data would cause
    * a BadConversion exception. This has been fixed, but 100%
    * consistency with MySQL server has not been targeted, so that other
    * non-numeric characters in data will still cause BadConversion
    * exception or error. As this API is used in applications, users
    * should provide feedback if full compatibility with MySQL server is
    * desired, in which case BadConversion exception or error would be
    * abolished in some of future versions
    * A new method in ColData class has been introduced. is_null()
    * method returns a boolean to denote if a column in a row is NULL.
    * Finally, as of this release, testing for NULL values is possible.
    * Those are columns with empty strings for which is_null() returns
    * true.
    * Some SPARC Solaris installations had C++ exception problems with
    * g++ 2.95.2 This was a bug that was fixed in GNU gcc, as from
    * release 2.95 19990728. This version was thoroughly tested and is
    * fully functional on SPARC Solaris 2.6 with the above version of
    * gcc.
    * A 'virtual destructor ' warning for Result class has been fixed
    * Several new functions for STL strings have been added. Those
    * functions (see string_util.hh) add some of the functionality
    * missing in existing STL libraries
    * Conversion for 64 bit integers on FreeBSD systems has been added.
    * On those systems _FIX_FOR_BSD_ should be defined in CXXFLAGS prior
    * to configuring. Complete conversion to the usage of functions for
    * integer conversion found in mysqlclient library is planned for one
    * of the next releases
    * A completely new, fully dynamic, dramatic and fully mutable result
    * set has been designed and will be implemented in some of 2.x
    * releases
    * Several smaller fixes and improvements, including defaulting
    * exceptions to true, instead of false, as of this version
    * An up-to-date and complete Postscript version of documentation is
    * included in this distribution
    * Large chunks of this manual are changed, as well as README and
    * TODO files.

1.6 (Feb 3 2000) Sinisa Milivojevic <sinisa@mysql.com>

    * This is a major release as it includes new features and major
    * rewrites
    * Automatic quoting and escaping with streams. It works
    * automatically , depending on the column type. It will work with <<
    * on all ostream derived types. it is paricularly handy with query
    * objects and strstreams. Automatic quoting and escaping on cout,
    * cerr and clog stream objects is intentionally left out, as quoting
    * / escaping on those stream objects is not necessary. This feature
    * can be turned of by setting global boolean dont_quote_auto to
    * true.
    * Made some major changes in code, so that now execute method should
    * be used only with SSQL and template queries, while for all other
    * query execution of UPDATE's, INSERT's, DELETE's, new method exec()
    * should be used. It is also faster.
    * New method get_string is inroduced for easier handling / casting
    * ColData into C++ strings.
    * Major rewrite of entire code, which led to it's reduction and
    * speed improvement. This also led to removal of several source
    * files.
    * Handling of binary data is introduced. No application program
    * changes are required. One of new example programs demonstrates
    * handling of binary data
    * Three new example programs have been written and thoroughly
    * tested. Their intention is to solve some problems addressed by
    * MySQL users.
    * Thorough changes is Makefile system has been made
    * Better configuration scripts are written, thanks to D.Hawkins
    * <dhawkins@cdrgts.com>
    * Added several bug fixes
    * Changed Manual and Changelog

1.5 (Dec 1 1999) Sinisa Milivojevic <sinisa@mysql.com>

    * Fixed bug in template queries, introduced in 1.4 (!)
    * Fixed connect bug
    * Fixed several bug in type_info classes
    * Added additional robustness in classes
    * Added additional methods for SQL type info
    * Changed Changelog and README

1.4 (Nov 25 1999) Sinisa Milivojevic <sinisa@mysql.com>

    * Fixed bug in store and storein methods
    * Fixed one serious memory leak
    * Fixed a very serious bug generated by gcc 2.95.xx !!
    * Added robustness in classes, so that e.g. same query and row
    * objects can be re-used
    * Changed sinisa_ex example to reflect and demonstrate this
    * stability
    * Changed Changelog and README
    * Few other bug fixes and small improvements and speed-ups

1.3 (Nov 10 1999) Sinisa Milivojevic <sinisa@mysql.com>

    * Fixed several erronous definitions
    * Further changed source to be 2.95.2 compatible
    * Expunged unused statements, especially dubious ones, like use of
    * pointer_tracker
    * Corrected bug in example file fieldinf1
    * Finally fixed mysql_init in Connection constructor, which provided
    * much greater stability !
    * Added read and get options, so that clients, like mysqlgui can use
    * it
    * Changed Changelog and README
    * Many other bug fixes.

1.2 (Oct 15 1999) Sinisa Milivojevic <sinisa@mysql.com>

    * First offical release. Version 1.0 and 1.1 were releases by Sinisa
    * before I (Kevin Atkinson) made him the offical maintainer,
    * Many manual fixes.
    * Changed README and Changelog
    * Changed source to be compilable by gcc 2.95.xx, tribute to Kevin
    * Atkinson <kevinatk@home.com>
    * Added methods in Connection class which are necessary for
    * fullfilling administrative functions with MySQL
    * Added many bug fixes in code pertaining to missing class
    * initializers , as notified by Michael Rendell <michael@cs.mun.ca>
    * Sinisa Milivojevic <sinisa@mysql.com> is now the offical
    * maintainer.

1.1 (Aug 2 1999) Sinisa Milivojevic <sinisa@mysql.com>

    * Added several bug fixes
    * Fixed memory leak problems and variables overlapping problems.
    * Added automake and autoconf support by loic@ceic.com
    * Added Makefile for manual
    * Added support for cygwin
    * Added example sinisa_ex (let modesty prevail) which used to crash
    * a lot when memory allocation, memory leak and overlap problems
    * were present. Smooth running of this example proves that all those
    * bugs are fixed
    * Corrected bugs in sql_query.cc regarding delete versus delete[]
    * and string length in manip.cc
    * Changed manual
* Changed version to 1.0
    * Changed README
    * Many other smaller things

1.0 (June 9 1999) Michael Widenius <monty@monty.pp.sci.fi>

    * Added patches from Orion Poplawski <orion@bvt.com> to support the
    * UnixWare 7.0 compiler
* Added patches from Orion Poplawski <orion@bvt.com> to support the
  UnixWare 7.0 compiler

.64.1.1a (Sep 27 1998)

    * Fixed several bugs that caused my library to fail to compile with
    * egcs 1.1. Hopefully it will still compile with egcs 1.0 however I
    * have not been able to test it with egcs 1.0.
    * Removed some problem causing debug output in sql++pretty.

.64.1a (Aug 1 1998)

    * Added an (almost) full guide to using Template Queries.
    * Fixed it so the SQLQuery will throw an exception when all the
    * template parameters are not provided.
    * Proofread and speedchecked the manual (it really needed it).
    * Other minor document fixes.

.64.0.1a (July 31 1998)

    * Reworked the Class Reference section a bit.
    * Minor document fixes
    * Added more examples for SSQLS.
    * Changed the syntax of equal_list for SSQLS from equal_list (cchar
    * *, Manip, cchar *) to (cchar *, cchar *, Manip).
    * Added set methods to SSQLS. These new methods do the same thing as
    * there corresponding constructors.
    * Added methods for creating a mysql_type_info from a C++ type_info.

.64.a (July 24 1998)

    * Changed the names of all the classes so they no longer have to
    * have Mysql in the begging of it. However if this creates a problem
    * you can define a macro to only use the old names instead.
    * The Specialized SQL Structures (formally known as Custom Mysql
    * Structures) changed from mysql_ to sql_.
    * Added the option of using exceptions thoughout the API.
    * ColData (formally known as MysqlStrings) will now throw an
    * exception if there is a problem in the conversion.
    * Added a null adapter.
    * Added Mutable Result Sets
    * Added a very basic runtime type identification for SQL types
    * Changed the document format from POD to LYX .
    * Am now using a modified version of Perceps to extract the class
    * information directly from the code to make my life easier.
    * Added an option of defining a macro to avoid using the automatic
    * conversion with binary operators.
    * Other small fixed I probully forgot to mentune.

.63.1.a

    * Added Custom Mysql Structures.
    * Fixed the Copy constructor of class Mysql
    * Started adding code so that class Mysql lets it children now when
    * it is leaving
    * Attempted to compile it into a library but still need help. As
    * default it will compile as a regular program.
    * Other small fixes.

.62.a (May 3 1998)

    * Added Template Queries
    * Created s separate SQLQuery object that is independent of an SQL
    * connection.
    * You no longer have to import the data for the test program as the
    * program creates the database and tables it needs.
    * Many small bug fixes.

.61.1.a (April 28 1998)

    * Cleaned up the example code in test.cc and included it in the
    * manual.
    * Added an interface layout plan to the manual.
    * Added a reverse iterator.
    * Fixed a bug with row.hh (It wasn't being included because of a
    * typo).

.61.0.a

    * Major interface changes. I warned you that the interface may
    * change while it is in pre-alpha state and I wasn't kidding.
    * Created a new and Separate Query Object. You can no longer execute
    * queries from the Mysql object instead you have to create a query
    * object with Mysql::query() and use it to execute queries.
    * Added the comparison operators to MysqlDate, MysqlTime and
    * MysqlDateTime. Fixed a few bugs in the MysqlDate... that effected
    * the stream output and the conversion of them to strings.
    * Reflected the MysqlDate... changes in the manual.
    * Added a new MysqlSet object and a bunch of functions for working
    * with mysql set strings.

.60.3a (April 24 1998)

    * Changed strtoq and strtouq to strtoll and strtull for metter
    * compatibility Minor Manual fix.
    * Changed makefile to make it more compatible with Solaris (Thanks
    * Chris H)
    * Fixed bug in comparison functions so that they would compare in he
    * right direction.
    * Added some items to the to do list be sure to have a look.

Deleted HACKERS.
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













































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
If you are going to make any changes to MySQL++, this file has some
hints and commentary you may find helpful.


Subversion Access
~~~~~~~~~~~~~~~~~
    To check out the current development version from the Gna!
    Subversion repository, say:

        $ svn co svn://svn.gna.org/svn/mysqlpp/trunk mysqlpp

    If you're a MySQL++ committer, use svn over ssh instead:
    
        $ svn co svn+ssh://LOGIN@svn.gna.org/svn/mysqlpp/trunk mysqlpp

    where LOGIN is your Gna! login name.  You will have to have your
    ssh public key(s) registered with Gna! for this to work.


Submitting Patches
~~~~~~~~~~~~~~~~~~
    If you wish to submit a patch to the library, please send it to
    the MySQL++ mailing list, or attach it to an entry in our bug
    tracker on Gna!  We want patches in unified diff format.

    The easiest way to get a unified diff is to check out a copy of
    the current MySQL++ tree as described in the previous section.
    Then make your change, cd to the MySQL++ root directory, and ask
    Subversion to generate the diff for you:

        $ svn diff > mychange.patch

    If your patch adds new files to the distribution, you can say
    "svn add newfile" before you do the diff, which will include
    the contents of that file in the patch.  (You can do this even
    when you've checked out the tree anonymously.)  Then say "svn
    revert newfile" to make Subversion forget about the new file.

    If you're making a patch against a MySQL++ distribution tarball,
    then you can generate the diff this way:

        $ diff -ruN mysql++-olddir mysql++-newdir > mychange.patch

    The diff command is part of every Unix and Linux system, and
    should be installed by default.  If you're on a Windows machine,
    GNU diff is part of Cygwin (http://cygwin.com/).  Subversion is
    also available for all of these systems.  There are no excuses
    for not being able to make unified diffs.  :)


Testing Your Proposed Change
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In v2.3.2, we added a new script called 'dtest'.  You run it
    like you would most of the examples, except that you don't need
    to run it via exrun:

        $ ./dtest [host] [user] [pass]

    This automatically runs most of the examples, captures the outputs
    to a file, and then compares that to a known-good run's outputs.
    The purpose of this is that, before you submit a patch, run dtest
    and see if it indicates that anything has changed.  If something
    has and you can't account for it, it represents a problem that
    you'll have to fix before submitting the patch.

    If your change purposely causes different outputs from a dtest
    run, remove the bmark.txt file, then re-run dtest and include
    the bmark.txt diffs with your patch.  This communicates to us
    the fact that you know there are differences and want the patch
    evaluated anyway.  Otherwise, we are likely to view the change
    as a bug.


Adding Support for a Different Compiler
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    MySQL++ uses the Bakefile system for creating project files
    and makefiles.  This allows us to make changes to a single set
    of files, and have the proper changes be made to all generated
    project files and makefiles.  In the past, we used more ad-hoc
    systems, and we'd frequently forget to update individual project
    files and makefiles, so at any given time, at least one target
    was likely to be broken.

    If MySQL++ doesn't currently ship with project files or makefiles
    tuned for your compiler of choice, you need to work through the
    Bakefile mechanism to add support.  We're not willing to do ad-hoc
    platform support any more, so please don't ask if you can send
    us project files instead; we don't want them.

    If you want to port MySQL++ to another platform, we need to be
    confident that the entire library works on your platform before
    we'll accept patches.  In the past, we've had broken ports that
    were missing important library features, or that crashed when built
    in certain ways.  Few people will knowingly use a crippled version
    of MySQL++, since there are usually acceptable alternatives.
    Therefore, such ports become maintenance baggage with little
    compensating value.


On Manipulating the Bakefiles and Autoconf Files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you're on a Unixy platform and change any of mysql++.bkl,
    configure.ac, or config/*, you must re-run the bootstrap script
    to regenerate the build files.  The bootstrap script also has
    other functions:

        $ ./bootstrap [pedantic] [no{doc,ex,lib,opt}] [configure flags]

    If you pass 'pedantic' to the bootstrap script, it will set up
    the autoconf build system so it turns on all of GCC's warnings and
    such.  It's useful to build the library in this mode when making
    changes to make sure there are no obvious problems with the code.

    If you pass 'nodoc', the documentation won't be considered a
    prerequisite for building the distribution tarball.  This is
    useful on systems where the documentation doesn't build correctly,
    and you only need to make a binary RPM.  That process requires
    a tarball, but doesn't need the documentation.  Don't distribute
    the tarball or SRPM that results, as they are broken.

    If you pass 'noex', the generated Makefiles and project files
    won't try to build any of the examples.

    If you pass 'nolib', the generated Makefiles and project files
    won't try to build the MySQL++ library.

    If you pass 'noopt', compiler optimization will be turned off
    on systems that use configure.  (It currently has no effect on
    MinGW or Visual C++.)

    You can pass any of the previous options in any order.  As soon as
    the bootstrap script sees an option that it doesn't understand,
    it stops processing the command line.  Any subsequent options
    are passed to the configure script.  See README.unix for more on
    configure script options.

    If you're on Windows and you change the Bakefile (mysql++.bkl),
    re-generating the Makefiles and project files from it is a
    little tricky.  The above procedure doesn't work because the
    native Win32 port of Bakefile is incomplete, and Bakefile doesn't
    build correctly under Cygwin.  Therefore, you need to run the
    bakefile program directly.  You'll use one of these two commands,
    depending on which compiler you're using:

        C:\> bakefile -f msvc6prj mysql++.bkl
        C:\> bakefile -f mingw -o Makefile.mingw mysql++.bkl


Maintaining a Private CVS Repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    You may find it helpful to maintain your own CVS repository.
    Whenever there is a new MySQL++ release, import it on the vendor
    branch like this:

        $ cvs import -m "Version 1.7.35" software/mysql++ mysql++ mysql++-1_7_35

    (This assumes that you have your CVSROOT environment variable
    set properly.)

    Update the HEAD branch like this:

        $ cd mysql++
        $ cvs update -PdA
        $ cvs update -j HEAD -j mysql++-1_7_35 -Pd
        $ cvs ci -m "merged 1.7.35 into HEAD"
        $ cvs tag mysql++-1_7_35-merged

    Then any changes you make can easily be tracked, and diffs can
    be produced with rdiff:

        $ cvs rdiff -ru mysql++-1_7_35 -r mysql++-1_7_35_equal_list \
            $(cat CVS/Repository) > equal_list.patch

Changes to INSTALL.
1
2
3

4
5
6
7
8
9



1






-
-
-
+
-
-
-
-
-
-
The installation procedure depends on the compiler you use to build
MySQL++.  See:

/usr/share/automake/INSTALL
	README.unix -   for Unix, Linux, Mac OS X, etc.
	README.cygwin - for Cygwin
	README.mingw -  for MinGW
	README.vc -     for Visual C++

Also see the main README file for things that apply to all systems.
Added LGPL.

































































































































































































































































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
		  GNU LIBRARY GENERAL PUBLIC LICENSE
		       Version 2, June 1991

 Copyright (C) 1991 Free Software Foundation, Inc.
    		    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

[This is the first released version of the library GPL.  It is
 numbered 2 because it goes with version 2 of the ordinary GPL.]

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it.  You can use it for
your libraries, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.

  Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library.  If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software.  To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.

  Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs.  This
license, the GNU Library General Public License, applies to certain
designated libraries.  This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.

  The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it.  Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program.  However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.

  Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries.  We
concluded that weaker conditions might promote sharing better.

  However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves.  This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them.  (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.)  The hope is that this
will lead to faster development of free libraries.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, while the latter only
works together with the library.

  Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.

		  GNU LIBRARY GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License").  Each licensee is
addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.
  
  1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

  You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

  2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

  If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Accompany the work with a written offer, valid for at
    least three years, to give the same user the materials
    specified in Subsection 6a, above, for a charge no more
    than the cost of performing this distribution.

    c) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    d) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License.  However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

  9. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded.  In such case, this License incorporates the limitation as if
written in the body of this License.

  13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number.  If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation.  If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission.  For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this.  Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

			    NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

		     END OF TERMS AND CONDITIONS

           How to Apply These Terms to Your New Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).

  To apply these terms, attach the following notices to the library.  It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!
Deleted LICENSE.
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
























































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
		  GNU LESSER GENERAL PUBLIC LICENSE
		       Version 2.1, February 1999

 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it.  You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.

  When we speak of free software, we are referring to freedom of use,
not price.  Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.

  To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

  To protect each distributor, we want to make it very clear that
there is no warranty for the free library.  Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

  Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

  Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License.  We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

  When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom.  The Lesser General
Public License permits more lax criteria for linking other code with
the library.

  We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License.  It also provides other free software developers Less
of an advantage over competing non-free programs.  These disadvantages
are the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

  For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard.  To achieve this, non-free programs must be
allowed to use the library.  A more frequent case is that a free
library does the same job as widely used non-free libraries.  In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

  In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software.  For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

  Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

		  GNU LESSER GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.
  
  1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.

  You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

  2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.

  If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Use a suitable shared library mechanism for linking with the
    Library.  A suitable mechanism is one that (1) uses at run time a
    copy of the library already present on the user's computer system,
    rather than copying library functions into the executable, and (2)
    will operate properly with a modified version of the library, if
    the user installs one, as long as the modified version is
    interface-compatible with the version that the work was made with.

    c) Accompany the work with a written offer, valid for at
    least three years, to give the same user the materials
    specified in Subsection 6a, above, for a charge no more
    than the cost of performing this distribution.

    d) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    e) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License.  However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

  9. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

  11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded.  In such case, this License incorporates the limitation as if
written in the body of this License.

  13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number.  If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation.  If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission.  For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this.  Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.

			    NO WARRANTY

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

		     END OF TERMS AND CONDITIONS

           How to Apply These Terms to Your New Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).

  To apply these terms, attach the following notices to the library.  It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.

    <one line to give the library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!


Added Makefile.am.














1
2
3
4
5
6
7
8
9
10
11
12
13
14
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# This includes sqlplus.spec _and_ sqlplus.spec.in 
#   (this way rpm -ta xxxx work)
EXTRA_DIST = @PACKAGE@.spec @PACKAGE@.spec.in @PACKAGE@-config.in

SUBDIRS = sqlplusint examples doc # devel

bin_SCRIPTS = sqlplus-config

CONFIG_FILE = @PACKAGE@-config-@SQLPLUS_MAJOR_VERSION@.@SQLPLUS_MINOR_VERSION@

$(CONFIG_FILE): @PACKAGE@-config
	cp $^ $@

@PACKAGE@-config: @PACKAGE@-config.in
Added NEWS.
Changes to README.
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




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


-
-
-
-
+
+
-
-
-
-
+
+

+
-
+


-
-
-
-
+
+

-
-
-
-
-
-
-
+
+
+

-
-
+
+
-
-
-
-
-
-
-
-
-
-

+
+

-
+
-
-
-
-
-
+
+
+
-

-
+

-
-
+
-
-
-
+
-
-
+
-
-
-
+
-

-
+
-
-
-
-
-

-
+
-
-
-
+
+
+

-
-
+
+
+
+
-
-
-
+
+

-
-
-
+
-
-
+

+

-
-
-
-
+
-
-
-

+
+
+

-
-
-
-
+
-
-
-

-
-
-
+
+

-
-
-
-
-
-
+

+
+

-
-
-
-

-
+
+

-
-
What It Is
~~~~~~~~~~
	MySQL++ is a C++ wrapper for MySQL's C API.  It is built
	around STL principles, to make dealing with the database
This is C++ API  library for MySQL.

	as easy as dealing with an STL container.  MySQL++ relieves
	the programmer of dealing with cumbersome C data structures,
	generation of repetitive SQL statements, and manual creation
	of C++ data structures to mirror the database schema.
Starting based of 1.2, this is now maintained by sinisa@cytanet.com.cy
as kevinatk@home.com doesn't have time to support this library anymore. 

He has made sinisa@cytanet.com.cy a new official maintainer, which will
	Its home page is http://tangentsoft.net/mysql++/
continue to keep mysql++ library under LGPL.


Prerequisites
~~~~~~~~~~~~~
	To build MySQL++, you must have the MySQL C API development
	files installed.
Original information from kevinatk@home.com:
---------------------------------------------------------------------

	On Unixy systems (Linux, Mac OS X, Cygwin, "real" Unix...),
	the MySQL development files are installed if you build MySQL
	from source.  If you installed MySQL as a binary package,
	then the development files are often packaged separately
	from the MySQL server itself.  It's common for the package
	containing the development files to be called something like
	"MySQL-devel".
After several people commented on how my quickie wrapper would be of
little use I decided to go all out and create a full featured
version.

	If you're building on Windows with Visual C++ or MinGW, you
	need to install the native Win32 port of MySQL from mysql.com.
To my knowledge this library requiures gcc 2.8 or egcc or better and of
course the mysql library.
	The development files are only included with the "complete"
	version of the MySQL installer, and some versions of this
	installer won't actually install them unless you do a custom
	install.  Another pitfall is that MySQL++'s project files
	assume that you've installed the current General Availability
	release of MySQL (v5.0 right now) and it's installed in the
	default location.  If you've installed a different version,
	or if MySQL Inc. changes the default location (which they
	seem to do regularly!) you'll have to adjust the link and
	include file paths in the project settings.

To compile the library and modify the file Configure aproprietly
and type make.

Additional Things to Read
I am working on trying to get this to compile into a library.
~~~~~~~~~~~~~~~~~~~~~~~~~
	Each major platform we support has a dedicated README.* file
	for it containing information specific to that platform.
	Please read it.

However I really don't know what I am doing. If you have some
experense with this please take a look at my makefile and uncomment the
appropriate lines and let me know if I am doing everything right.
	For authorship information, see the CREDITS file.

	For license information, see the LICENSE file.
For more information please see the manual.

	If you want to change MySQL++, see the HACKERS file.

I developed it using egcc ver 1.02 (I think) from the Debian hamm
	You should have received a user manual and a reference manual
	with MySQL++.  If not, you can read a recent version online:

package with kernel 2.0.33 and a Cryix P150+ cpu.  I am also using
		http://tangentsoft.net/mysql++/doc/

Mysql 3.21.25 that is in the non-free section of the Debian
	Search the MySQL++ mailing list archives if you have more
	questions:

distribution.
		http://lists.mysql.com/plusplus/


Be sure to let me know what you think.  I depend on your feedback.
Building the Library
~~~~~~~~~~~~~~~~~~~~
	As of version 2.1, MySQL++ uses the Bakefile build system. This
	tool creates platform-specific project files and makefiles. We
	currently support these options:

	autoconf:
Thanks,
		For Unixy platforms, including Linux, Mac OS X, and
		Cygwin. See README.unix for details. Supplementary
		details for Cygwin are in README.cygwin.
I can be reached at kevinatk@home.com
--------------------------------------------------------------------
End of original README by Kevin Atkinson

	Visual C++:
		We ship Visual C++ 6 project files, but MySQL++ only

Since October 1999, all maintenance has been transferred to Sinisa
Milivojevic (sinisa@cytanet.com.cy) and Michael Widenius (monty@mysql.com).

		works with Visual C++ 7.1 (a.k.a. Visual Studio 2003)
		or newer. Your version of Visual Studio will upgrade
		these project files for you. See README.vc for details.
Send your feedback to any of these addresses, or even better to the
mailing list mysql-plusplus@lists.mysql.com.

	MinGW:
		We ship Makefiles made for MinGW. These currently only
		work for building static versions of the library,
Since versin 1.1, mysql++ has been prepared to be built with automake and
		which has licensing ramifications. See README.mingw
		for details.
autoconf. 

This will make compilation and  installation much easier. 

Example Programs
~~~~~~~~~~~~~~~~
	You may want to try out the programs in the examples
	subdirectory to ensure that the MySQL++ API and your
You should cd to the root of source directory and run ./configure.
	MySQL database are both working properly.  Also, these
	examples give many examples of the proper use of MySQL++.
	See README.examples for further details.

If you are running it several times, because you have problems, do delete 
config.cache. In case of the problem config.log contains more info on
it's whereabouts.

Unsupported Compliers
~~~~~~~~~~~~~~~~~~~~~
	If you're on Windows but want to use some other compiler
	besides Visual C++ or GCC, you are currently on your own.
After configure is run, config.h and Makefiles are generated. 
	There have been past efforts to port MySQL++ to other Windows
	compilers, but for one reason or another, all of these ports
	have died.

	On Unixy systems, GCC still works best.  "Native" compilers
	and third-party compilers may work, but you're on your own
	to get it working.
If you wish to install mysql++ in a root directory other then /usr/local,
you should run configure with --with-prefix=.....

	We have nothing in particular against these unsupported
	systems.  We just lack the time and resources to support
	everything ourselves.  If you are sufficiently motivated to
	get MySQL++ working on one of these alternate systems, see
	the HACKERS file first for guidance.  If you follow the advice
	in that file, your patch will be more likely to be accepted.
Configure contains description of other switches available.

After running configure, run make and make install. Libs will be
installed in prefix/lib and include files in prefix/include/mysql++.

If You Want to Hack on MySQL++...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	If you intend to change the library or example code, please
	read the HACKERS file.

	If you want to change the user manual, read doc/userman/README.
Since version 1.3, mysql++ is fully compliant with latest 2.95.xx series
of compilers.

	If you want to change the reference manual, see the Doxygen
	manual: http://www.stack.nl/~dimitri/doxygen/manual.html
Deleted README.cygwin.
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

































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Prerequisite: Build MySQL
~~~~~~~~~~~~~~~~~~~~~~~~~
	Before you can build MySQL++, you need to build the MySQL
	client library from source.  This is necessary because
	Cygwin programs work best when linked to Cygwin libraries.
	You do not need to build a Cygwin version of the MySQL server;
	it's still best to use the native Win32 version of that.

	The MySQL client library does not build correctly out of
	the box.  The best instructions I've found covering the
	necessary changes are here:

		http://cygwin.com/ml/cygwin/2004-11/msg00159.html

	I recommend that you use MySQL v4.1.x at this time.  Skip the
	step changing the pthread stuff in my_thr_init.c, as this
	change has already been made in recent versions of MySQL.

	With the changes applied, build and install the client library
	like so:

	$ autoreconf --install --verbose --force
	$ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
	    --infodir=/usr/share/info --mandir=/usr/share/man \
        --disable-shared --without-{debug,readline,libedit,server}
	$ make
	$ make install


Building the Library and Example Programs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	With that done, you can build MySQL++ just as you would most
	other Unix programs.  See README.unix for details.
Deleted README.examples.
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














































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Building the Examples
~~~~~~~~~~~~~~~~~~~~~
    If you're installing MySQL++ from the source tarball, the example
    programs get built when you build the library.  If you change
    any example code, just say 'make' to rebuild the examples.
    The examples are built against the headers and library in the
    lib subdirectory, not against the ones you may have installed
    elsewhere on the system.

    If these example files were installed on your system as part of
    the -devel RPM, copy all the files to a directory you can write
    to, then say 'make' in that directory.  This uses a simplified
    Makefile, which builds the examples against the headers and
    libraries installed in the system directories.


Getting Started with the Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    MySQL++ is built as a shared library on most systems, and a DLL
    on Windows.  Since it isn't built in the same directory as the
    examples, this means that your system won't be able to find the
    library without help until you install it.  Since you generally
    want to run the examples _before_ installing the library, to test
    that the library actually works, we need a workaround.

    That workaround is the exrun script.  There are two versions,
    a Bourne shell script called just exrun for POSIX systems, and
    exrun.bat for Windows.

    Before running the other examples, you must first create the
    sample database.  On POSIX systems, you do that like so:

        $ ./exrun resetdb [host] [user] [password] [port]

    On Windows, that would instead be:

        C:\mysql++\> exrun.bat resetdb [host] [user] [pass] [port]

    If you mistakenly run resetdb directly instead of through exrun,
    it will either fail to run because it can't find the MySQL++
    library, or it will find an old version and complain about it.
    None of the other examples are protected against mixed versions
    in this way, but since you have to run resetdb before all the
    other examples, this should pose no problem.

    You can give as few of the parameters as you want, but they must
    be in that order.  That is, if you want to give a user name,
    you must give the host first.  It defaults to localhost with
    your user name, no password, and the default MySQL port (3306).


Running the Other Command Line Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The following examples use the database set up by resetdb, and
    have the same command line format as resetdb:

        simple1: Shows the item names for all records in the sample
            stock table.  Try this one if you do nothing else.

        simple2: Similar to simple1, but it displays all columns
            from the sample stock table, not just the item name.

        simple3: Same as simple2, except that it retrieves the data
            with a "use" query instead of a "store" query.  See the
            user manual for the difference between these methods.

        custom1-6: Demonstrates the SSQLS features.  These examples
            are explained in the user manual.

        usequery: Demonstrates Query::use().  Unlike simple3, which
            also showcases this function, this one shows how use
            queries interact with exception handling: when you walk
            past the end of a "use" query set with exceptions enabled,
            MySQL++ throws an exception to indicate end of results,
            which you must catch.

        multiquery: MySQL++ allows you to issue multiple queries at
            once, and get the results as separate sets.  This shows
            that, and also how to use stored procedures, which return
            their results in the same way as a multiquery.

        tquery: A simple example showing how to use the template query
            facility.

        xaction: Shows how to use the Transaction class to create
            transaction sets which automatically roll back if not
            explicitly committed.

        store_if: Demonstrates the Query::store_if() method, which
            allows you to store the results of a query in an STL
            container conditionally.  Think of it as a more powerful
            alternative to the SQL WHERE clause.

        for_each: Demonstrates the Query::for_each() method, which
            allows you to execute a query and call a functor on each
            returned row.  This example uses this to gather statistics
            on the sample table's contents.

        load_jpeg: Inserts a JPEG file into the sample database,
            for use by the cgi_jpeg example.  (See below.)  Unlike
            the other examples, this one takes the last command
            line argument to be a JPEG file name.  We've included
            examples/logo.jpg as a sample, if you want to use that.

        fieldinf1: Shows how to get information about the fields in
            a result set.  (Types, etc.)

        dbinfo: Dumps a bunch of information about the database
            server and the tables in its 'mysql' database.
    
    If you run the load_jpeg example, you should consider also
    playing with the other half of the demonstration, cgi_jpeg.
    To run it, you'll need to install MySQL++ on a machine with
    a web server, then copy the cgi_jpeg program to the server's
    CGI directory.  For example, on a stock Red Hat type box,
    that would be /var/www/cgi-bin.  At that point, a request like
    http://my.server.com/cgi-bin/cgi_jpeg?id=1 should show the
    JPEG you loaded.  The ID value to use will be that reported
    by load_jpeg.


Dedicated Windows Examples
~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you're a Visual C++ user, there are two examples specially
    created for you:

        examples\vstudio\mfc.vcproj: A GUI replacement for the simple2
            example, it simply logs in and displays the stock table's
            contents.  Uses good old C++ and MFC.

        examples\vstudio\wforms.vcproj: The same thing, only written in
            C++/CLI and using Windows Forms.  We needed a second example
            for two reasons.  First, string handling is quite different
            under .NET than in unmanaged C++.  Second, many developers
            are now using Visual Studio Express, which doesn't include
            MFC.  Please read README.vc before trying to run this example.
            The MySQL++ build settings must be modified before it will
            run correctly.

    Before trying to run these examples, run the updexdll.bat file
    in the top MySQL++ directory.  This copies the built mysqlpp.dll
    files into the Windows examples' EXE output directories so you
    can run them before you're ready to formally install the DLL on
    your system.

    Open examples\vstudio\mysqlpp_gui_examples.sln to begin working
    with these examples.  They only work correctly in Visual Studio
    2005 right now.  If you want to backport them to VS 2003, it's
    probably not hard, and we will accept patches for this.  The main
    difficulty is that VS 2003 supports Managed C++, which isn't
    the same thing as C++/CLI.

    The main justification for these examples is that Unicode is
    handled differently in Windows GUI programs than on the POSIX
    systems where MySQL++ was born and raised.  In earlier versions
    of MySQL++, the command line examples had very limited Unicode
    support on Windows, but it was unrealistic and confusing.  Now the
    command line examples don't even try to handle Unicode on Windows,
    leaving that up to these new GUI examples.


Special exrun Capabilities
~~~~~~~~~~~~~~~~~~~~~~~~~~
    The Bourne shell version of the exrun script has a few features
    not avaiable in the Windows batch file version.  These features
    let you run the examples under various debugging tools.

    You can get simple gdb debugging if you run an example like this:

        $ ./exrun gdb simple1 foo bar qux

    The script also supports valgrind, in memory leak testing mode:

        $ ./exrun valgrind simple1 foo bar qux
Deleted README.mingw.
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

















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
MinGW Version
~~~~~~~~~~~~~
	You need a fairly recent version of MinGW for MySQL++ to work.
	As I write this, the current release version includes GCC
	3.4.2, which has known problems.  Unless they've released
	a newer version since I wrote this, you'll probably need to
	install the "candidate" version for best compatibility.


Prerequisite: Create Import Library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Before you can build MySQL++ with MinGW, you will need to
	create a MinGW-compatible import library for MySQL's C API
	library.  Using the current default install path for MySQL and
	assuming MySQL++ is in c:\mysql++, the commands to do this are:

		cd C:\Program Files\MySQL\MySQL Server 5.0\lib\opt
	    dlltool -k -d c:\mysql++\libmysqlclient.def -l libmysqlclient.a


Building the Library and Example Programs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	Now you can build MySQL++ with this command:
	
		mingw32-make -f Makefile.mingw

	Notice that we're using the MinGW-specific version of GNU
	make, not the Cygwin or MSYS versions.	This is in order to
	get proper path separator handling.

	If MySQL isn't in C:\Program Files\MySQL\MySQL Server 5.0\ you have
	two options:
	
		- The simplest is to edit Makefile.mingw.  This is
		  a generated file, but if that's all the only change
		  to MySQL++ you need, it works fine.

		- If you're doing deeper work on MySQL++, you
		  should make your changes in mysql++.bkl instead.
		  Then to generate Makefile.mingw from that file,
		  you will need the Win32 port of Bakefile from
		  http://bakefile.sf.net/  The command to do that is:

			  bakefile -f mingw -o Makefile.mingw mysql++.bkl

    Once the library is built and you're satisfied that it's working
    correctly, you can run the install.bat file at the project
    root to automatically install the library files and headers in
    subdirectories under c:\mysql++.
Deleted README.unix.
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





























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Building the Library and Example Programs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	MySQL++ uses the GNU autoconf, so you can build it with the
	standard commands:

	# ./configure
	$ make
	$ su
	# make install

	On Linux, you also need to run 'ldconfig' as root after
	installing the library.  You may need to add the library's
	installation directory to /etc/ld.so.conf before you do this,
	particularly if you installed to /usr/local.


Configure Options
~~~~~~~~~~~~~~~~~
	The configure script takes several interesting options. Say:

		$ ./configure --help

	to get a list.  Some of the more interesting flags are:

	--prefix:

		If you wish to install mysql++ in a root directory
		other than /usr/local, run configure with
		--prefix=/some/dir/name

	--with-mysql*:

		If you installed MySQL in an atypical location,
		the configure script will not be able to find the
		library and header files without help.	The simplest
		way to clue configure into where MySQL is installed
		is with the --with-mysql option.  Try something
		like "--with-mysql=/usr/local/mysql", for instance.
		The configure script will then try to guess which
		subdirectories under the given directory contain the
		library and include files.

		If that still doesn't work, use --with-mysql-include
		and --with-mysql-lib instead.  As with --with-mysql,
		configure can often guess which subdirectory under the
		given directory contains the needed files, so you don't
		necessarily have to give the full path to these files.

	--enable-thread-check:

		Builds MySQL++ with threads support, if possible.
		
		This option simply turns on two tests: first, that
		your system uses a compatible threading library; and
		second, that the thread-safe version of the MySQL C API
		library (libmysqlclient_r) is installed and working.
		If both of these are true, you get a thread-aware
		version of MySQL++.  "Thread-aware" means that the
		library does make an effort to prevent problems, but
		we don't guarantee that all possible uses of MySQL++
		are thread-safe.
Deleted README.vc.
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


















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Prerequisites
~~~~~~~~~~~~~
    MySQL++ requires Visual Studio 2003 or later.  Earlier versions
    did not support a sufficiently broad subset of Standard C++.

    You also need to have MySQL installed.  The installer may have
    given you the option of whether to install the development files
    or not; if you didn't let it install them, you need to reinstall.


Building the Library and Example Programs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    As of MySQL++ v2.2, there is only one set of project files
    in the top level directory for MySQL++.  We ship VC++6 style
    project files (.dsw and .dsp instead of .sln and .vcproj) due to
    a limitation of the tool we use to generate the project files.
    Just let Visual Studio convert these to the new format.

    If you installed MySQL somewhere other than 
    
        C:\Program Files\MySQL\MySQL Server 5.0\
        
    you need to change the project file settings.  The simplest way
    to do this is to change the link and include file directories in
    the project settings directly.  Although these are technically
    generated files and it's generally bad practice to change generated
    files, if that's all the only change to MySQL++ you need, this
    is harmless.  See below if you want to change the actual source
    files that create the project files.

    Be sure to build both the Debug and Release versions of the
    library.  You will need them both because when you build your
    program in Release mode, it won't work with mysqlpp.dll built
    in Debug mode.  The converse may also be true, but I'm not sure.
    The simplest way to ensure that you're running your program against
    the correct DLL is to copy the debug version of the MySQL++ DLL
    into your program's Debug build directory, and the same for the
    release version.

    With the library built, run at least the resetdb and simple1
    examples to ensure that the library is working correctly.
    See README.examples for further details.

    Once you're sure the library is working correctly, run the
    install.bat file at the project root to automatically install
    the library files and headers in subdirectories under c:\mysql++.


Using MySQL++ in an MFC Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If you don't already have a project set up, open Visual Studio, say
    File::New::Project, then choose Visual C++::MFC::MFC Application.
    Go through the wizard setting up the project as you see fit.

    Once you have your project open, right click on your top-level
    executable in the Solution Explorer, choose Properties, and make
    the following changes.  (Where it doesn't specify Debug or Release,
    make the change to both configurations.)

        o Append the following to C/C++::General::Additional Include
          Directories:

            C:\Program Files\MySQL\MySQL Server 5.0\include,
            C:\mysql++\include

        o Under C/C++::Code Generation change "Runtime Library" to
          "Multi-threaded Debug DLL (/MDd)" for the Debug
          configuration.  For the Release configuration, make it
          "Multi-threaded DLL (/MD)".

        o Append the following to Linker::General::Additional Library
          Directories for the Debug configuration:

            C:\Program Files\MySQL\MySQL Server 5.0\lib\debug,
            C:\mysql++\vc\debug

          For the Release configuration, make it the same, but
          change the 'debug' directory names to 'opt'.

        o Under Linker::Input add the following to "Additional
          Dependencies":
          
            libmysql.lib wsock32.lib mysqlpp.lib

    You may want to study examples\vstudio\mfc\mfc.vcproj to see
    this in action.  Note that some of the paths will be different,
    because it can use relative paths for mysqlpp.dll.


Using MySQL++ in a Windows Forms C++/CLI Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Before you start work on getting MySQL++ working with your own
    program, you need to make some changes to the MySQL++ build settings.
    Open mysqlpp.sln, then right-click on the mysqlpp target and select
    Properties.  Make the following changes for both the Debug and
    Release configurations:

        o Under Configuration Properties::General, change "Common
          Language Runtime support" to the /clr setting.

        o Under C/C++::Command Line, remove the /EHsc from the
          Additional Options section.

    If you have already built MySQL++, be sure to perform a complete
    rebuild after changing these options.  The compiler will emit several
    C4835 warnings after making those changes, which are harmless when
    using the DLL with a C++/CLI program, but which warn of real problems
    when using it with unmanaged C++.  As a result, it's probably best
    if you don't install the resulting DLL in a system level directory.
    I'd recommend copying it only into the same directory as the EXE.

    Once you have MySQL++ built with CLR support, open your program's
    project.  If you don't already have a project set up, open Visual
    Studio, say File::New::Project, then choose Visual C++::CLR::Windows
    Forms Application.  Go through the wizard setting up the project as
    you see fit.

    The configuration process isn't much different from that for an
    MFC project, so go through the list above first.  Then, make the
    following changes particular to .NET and C++/CLI:

        o Under Configuration Properties::General change the setting
          from /clr:pure to /clr.  (You need mixed assembly support
          to allow a C++/CLI program to use a plain C++ library like
          MySQL++.)

        o For the Linker::Input settings, you don't need wsock32.lib.
          The mere fact that you're using .NET takes care of that
          dependency for you.

    In the MFC instructions above, it said that you need to build it
    using the Multi-threaded DLL version of the C++ Runtime Library.
    That's not strictly true for MFC, but it's an absolute requirement
    for C++/CLI.  See the Remarks in this MSDN article for details:

        http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

    You may want to study examples\vstudio\wforms\wforms.vcproj to see
    all this in action.  Note that some of the paths will be different,
    because it can use relative paths for mysqlpp.dll.


Working With Bakefile
~~~~~~~~~~~~~~~~~~~~~
    MySQL++'s Visual Studio project files aren't maintained directly.
    Instead, they're generated from mysql++.bkl using a tool called
    Bakefile, from http://bakefile.sourceforge.net/  We do it this
    way so we can support multiple platforms and build systems in a
    common way.

    Therefore, if you need to make changes to the project files
    and want to submit those changes back to the MySQL++ project,
    you need to do your changes to mysql++.bkl instead of directly to
    the project files.  There is a native Win32 version of Bakefile up
    on that web site.  Download that and put the directory containing
    bakefile.exe in your Windows PATH.

    The documentation on the Bakefile web site isn't wonderful, but
    is adequate for most things.  If you can't find documentation
    for the feature you need, it's quite likely that Bakefile just
    doesn't support it.  There are things you can do to the project
    settings in Visual Studio that you can't do in Bakefile, since
    it's a cross-platform tool.

    Once you've made your changes, generate the Visual C++ project
    files with this command:

        bakefile -f msvc6prj mysql++.bkl


If You Run Into Problems...
~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Especially if you have linking problems, make sure your project
    settings match the above.  Visual C++ is very picky about things
    like run time library settings.  When in doubt, try running one
    of the example programs.  If it works, the problem is likely in
    your project settings, not in MySQL++.

Deleted Wishlist.
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






































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Patches for any of these thoughtfully considered!  See the HACKERS file
for instructions on sending patches.

Here's a meta-item that doesn't really fit into any of the categories
below: any time you must hand-roll some SQL code in your program,
consider whether it could be reduced to an API feature that would be
widely useful.  Patches or proposals of this sort are always welcome.


v2.x Features
-------------
    Items in this section may slip to v3.0.  The only thing that
    puts an item in this section instead of the v3.0 one is that
    it can be done without breaking the ABI, which would force
    a feature to v3.0.

    o Add ConnectionPool class, described in this post:

      http://lists.mysql.com/plusplus/6631
    
    o Extend the manipulators to handle nullable versions of
      the types we already support.  Should just be a matter of
      duplicating the existing type-specific manipulator functions,
      and wrapping the types in Null<>.

    o Add a few features to date and time classes:

      - It may be possible to get some nice syntactic sugar,
        such as a way to call SQL functions like NOW() when
        inserting certain Date/Time objects into a Query stream.

      - Arithmetic features?  (See "Practical Algorithms for
        Programmers" by Binstock and Rex.)

    o Add conditional code to the Lockable mechanism to use platform
      mutexes if available, to implement these MySQL C API
      restrictions:

      - Only one query executing at once per connection

      - For "use" queries, Connection (and therefore Query) object must
        remain locked until last row is consumed

      - Safest to have one Connection per thread.  Rules for sharing:
        http://dev.mysql.com/doc/mysql/en/threaded-clients.html

      Need some way to call mysql_thread_init() and
      mysql_thread_end() per thread.  Also, work in some way to
      call mysql_thread_safe() automatically, perhaps the first
      time through the function that calls mysql_thread_init().
      If the C API library reports that it is not thread-safe,
      report this to the caller, perhaps through an exception,
      or simply by refusing to init more than one thread.

    o Build a forward iterator mechanism for ResUse.  Make it
      general enough that you can use it with STL algorithms
      like find_if().  Then make an example to demonstrate this
      augmentation of SELECT.  Also, update usequery example
      to use the iterator.  Tricky bit: how do we make it not
      interfere with subclass Result's random-access iterator?

    o It may be possible to optimize the use of ColData in the return
      from Row::operator[].  Currently, that operator returns a
      temporary ColData object, which contains a copy of the field data
      in its std::string base class instead of a const char* pointer
      to data within the Row object.  If the caller just wants a
      const char*, we can avoid at least one copy here, maybe two. See:

      http://lists.mysql.com/plusplus/4451
      http://lists.mysql.com/plusplus/4460

    o Add Chris Frey's packarray class?


v3.0 Plan
---------

    Version 3.0 is primarily for those changes that will break
    the ABI.  (i.e. removing functions, changing function
    signatures, etc.)  This plan is very tenuous.  Some of this
    could slip to v4.0.

    o Remove all remaining query_reset function parameters, unless
      the function doesn't actually override them.

    o Refactor option mechanism in Connection class into its own
      class.  There are a whole lot of functions, structs and
      enums related to this.

    o Connection::bad_option() should save its built error message
      in an instance variable, and Connection::error() should
      use that when set, so you can get an explanation of option
      setting errors when exceptions are disabled.

    o The Connection::connect() arguments for turning on compression
      and setting the connection timeout should be removed.  These
      can be set directly using Connection::set_option().

    o Add table creation ability to SSQLS.  It has the schema, so...

    o SSQLS should allow table column order to differ from
      structure field order.  Not only will this decouple the
      definitions, it will allow queries for a subset of the fields
      without restricting you to the first N contiguous fields.
      This will require doing a by-name lookup for each field
      when populating it from the MYSQL_ROW object, but if you
      need the highest possible speed, you shouldn't be using
      SSQLS to begin with.

    o Evaluate whether Query's copy ctor should be made private.
      Copying these objects probably never makes sense.

    o Rename Query::success() and Query::success_.  The names imply
      that they only have meaning once a query is tried, but
      that isn't true.  They're an indicator of whether the
      object has had any problems at all, not just problems in
      query execution.

    o Rename Query::def to Query::tquery_defaults.  Makes its
      purpose clearer.  Also, examine all other public data
      members, to see if they have a similar problem.

    o Connection::error() returns const char*, while Query::error()
      returns std::string.  Pick one.

    o Remove MutableColData.  It's only used once in the library,
      within myset.h, and that usage is inefficient to the point
      of wanting replacement anyway.

    o Turn ColData_Tmpl<T> into a concrete class.  Use private
      std::string instance as buffer, and replicate the std::string
      interface publically, delegating to that buffer.
      
    o Use this new class in place of ColData_Tmpl<const_string>, 
      and remove const_string class.

    o More robust fix for the Query stream base class init problem:
      http://www.boost.org/libs/utility/base_from_member.html

      Requires inheritance change, which is why it has to be in v3.

    o Query::str() appends a null byte to the end of the string it
      returns each time it is called.  It is arguable whether it
      should append a null byte at all, since std::string doesn't
      need it.  But even if it does, it at least should recognize
      when the string already has a null, and not keep adding them
      when it is called repeatedly.  See this thread for details:

        http://lists.mysql.com/plusplus/6252

    o Should sql_timestamp typedef not be for DateTime class, not Time
      class?

    o Apply Richard Forrest's iterator patch.

    o The quote manipulator (and presumably the others as well) don't
      work properly with char*.  See this for details:

          http://lists.mysql.com/plusplus/5617

    o Change the unsigned int overloads for operator[] on
      const_subscript_iterator and its subclasses from unsigned
      int to a plain int.  This should fix the ambiguous overload
      problems, such as with row[0].

      See the following threads for reference:
          http://lists.mysql.com/plusplus/4947
          http://lists.mysql.com/plusplus/4952
          http://lists.mysql.com/plusplus/4960
    
    o Several MySQL++ functions wrap the MySQL C API too literally:
      they indicate success by returning 0 instead of true,
      as most other wrapper functions do.

    o Apply Waba's patch allowing Null<T> fields in SSQLSes:
      http://lists.mysql.com/plusplus/5433

    o Deprecate sql_create_basic_*  They have less functionality
      and they're no easier to use than sql_create and friends.

    o Consider whether some of the current boilerplate can be
      made into a base class that all SSQLSes derive from.  Some
      template functions like Query::insert<T> might become regular
      member functions, taking a reference to the SSQLS base class.

    o Abstract all uses of MySQL C API functions into a database
      driver class with a generic interface.  This is a step
      towards database-independence, without the parallel class
      hierarchy required by the MySQL++ 1.7 design.  Also, it
      will make it easier to make class Connection completely
      friend-less.  Right now, the main reason it needs friends
      is because these other classes make C API calls using its
      private MYSQL data member.  The other reasons for it having
      friends aren't nearly as compelling, so it wouldn't be
      hard to justify redesigning Connection to eliminate these
      final reasons.

      While it would be easy to have just one global database
      driver object, it's probably going to be necessary to have
      one per Connection.  Consider what happens when you have one
      program connected to two very different MySQL databases,
      and you indirectly call C API functions that take MYSQL
      parameters.  It's likely that those calls are supposed
      to behave different, depending on the data in that MYSQL
      object; for instance, different character encodings in the
      selected databases.  So, there must somehow be a way to pass
      the database driver's instance pointer down to all objects
      that will need to use the driver.  A side benefit is that
      a single program could talk to multiple different database
      server types.  Imagine a program for importing data from
      PostgreSQL and loading it into a MySQL table, for instance.

    o Query::preview() is just an alias for Query::str().
      Pick one.

    o Remove Query::execute(), store() and use() overloads taking
      a SQLQueryParms object reference.  With the changes in
      v2.2 making the single SQLString overload the end-point
      of the call chain, this just adds one more layer to the
      call chain.  Oh, sure, maybe there is someone out there who
      uses this...but probably not.  Much more likely it's just
      an outdated step that adds nothing to the user experience.

    o The sense of Lockable::lock()'s return value is backwards.
      It should return true if it succeeds in locking the object.

    o Remove simple const char* version of Query::execute(),
      store(), and use()?  SQLString already has a conversion
      ctor taking a const char* string, so there should be no
      need for this explicit overload.



Future Features
---------------

    These changes are not assigned to any particular version.
    They could happen at any time.  If you want one to appear at
    some definite date, get coding and provide a patch!

    o SSQLS v2.  Not sure how it will look yet, but there are ideas
      in play, and patches to study.

    o Figure out some way to name debug DLL and library under VC++
      differently (trailing 'd'?) to prevent some problems due
      to mixing debug and release programs and MySQL++ DLLs.
      This appears to require changes to Bakefile, or some sort of
      post-build hackery.

    o Create adaptors for std::bitset, for storing binary data in a
      MySQL table.  Make two options available, one for storing
      the return from bitset::to_ulong() in an UNSIGNED INTEGER
      column, and another for storing a larger set of bits in a
      more flexible way, perhaps as a BLOB.

    o Row object currently depends on the associated ResUse object
      to stick around through all calls to .at(), because it needs
      the list of field types in the result set to construct
      ColData objects.  This means it's not possible to store
      the result of several queries before accessing the data.
      Currently, this is just a documented limitation, but it
      would be nice if there were a clean way to avoid this.
      Obviously you could just copy the type list when constructing
      the Row object, but that seems pointlessly inefficient.

    o Define operator<< for Fields, Row, ResUse, etc.  In other
      words, there should be a way to get a user-readable version
      of received data without a lot of code.  Perhaps use a CSV
      output format, or a mysql(1) one (ASCII grid).

    o manip.cpp uses mysql_escape_string(), which doesn't take the
      selected database's character set into account.  To do that,
      you must use mysql_real_escape_string(), which differs
      by taking a MYSQL instance as an additional parameter.
      The problem is, Connection owns the relevant MYSQL instance,
      and the manipulator functionality is implemented in global
      functions (operator<<() and such) so they have no direct
      access to the relevant Connection object.

      The key question for all operator<<'s for manipulators
      to ask is, "which Query object am I being inserted into?"
      From there, you can look up the associated Connection object.

      In some cases, this answer to the question is easy, because
      the operator takes an ostream parameter, which can be
      dynamically cast to Query.  From there, it's just a lookup
      table problem.
      
      Other operator<<'s don't take an ostream, but they do take
      a manipulator.  Right now, manipulators are just enum values,
      but they could in fact be classes.  Classes can carry data,
      so there may be a way to "bind" them to the appropriate
      Connection object.  If not, then perhaps some other method
      will pop out of the database driver class idea.  The driver
      object may be able to look up a suitable Connection object
      for the manipulators.

    o MySQL++ handles automatic quoting and escaping differently
      for cout and cerr than for Query streams.  This should
      probably be simplified so that automatic quoting is only
      done for Query streams.  No other stream type should be
      treated specially.

    o Some field_list() functions use the do_nothing manipulator,
      while others use the quote manipulator.  Need to pick one.
      In the vast majority of cases, quoting won't be necessary,
      so make that the default.  But, it should be possible to turn
      it on, if needed.  If all uses of quoting are in template
      code, this can be a #define, allowing different programs
      built on the same system to get different quoting rules.
      Otherwise, it will probably have to be a configure script
      flag, which will "burn" the choice into the built binary.

    o User-settable floating-point comparison precisions?
      Something like this: http://lists.mysql.com/plusplus/3984
      As it currently stands, sql_cmp(double,double) is foolish.
      One shouldn't do exact equality comparison on floating
      point values.

    o Consider using MySQL C API enum constants in
      mysql_type_info::types definition instead of hard-coded
      values.  This could potentially break a lot of
      infrastructure, though, so do it only with care.

    o Support prepared statements.

Added autogen.sh.


















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#!/bin/sh

libtoolize --automake
aclocal 
autoconf
autoheader

for fn in AUTHORS ChangeLog NEWS README
do
  if [ ! -e  "$fn" ]
  then
    touch "$fn"
  fi
done
  
automake -a
./configure $*

Deleted bootstrap.
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

















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/bin/sh

ARGS=1
BF_OPTIONS=
while [ $ARGS != 0 ]
do
	case "$1" in
		nodoc)
			BF_OPTIONS="-DBUILDDOCS=no $BF_OPTIONS"
			shift
			;;

		noex)
			BF_OPTIONS="-DBUILDEXAMPLES=no $BF_OPTIONS"
			shift
			;;

		nolib)
			BF_OPTIONS="-DBUILDLIBRARY=no $BF_OPTIONS"
			shift
			;;

		noopt)
			export CXXFLAGS="-g -O0"
			shift
			;;

		pedantic)
			export CXXFLAGS="-g -O2 -ansi -pedantic -Wall -W -Wold-style-cast -Wfloat-equal -Wwrite-strings -Woverloaded-virtual -Wno-long-long"
			shift
			;;

		*)
			ARGS=0
			;;
	esac
done

rm -f config.cache
set -x

./rebake $BF_OPTIONS &&
	bakefile -f gnu -o Makefile.simple -DBUILDLIBRARY=no mysql++.bkl &&
	aclocal -I config -I /usr/local/share/aclocal &&
	autoheader &&
	autoconf &&
	./reconf --enable-maintainer-mode $* &&
	make lib/custom.h lib/querydef.h

Deleted cleanmf.
1
2
3
4




-
-
-
-
#!/bin/sh
rm -f *.{ds?,ncb,sln,suo,vcproj}
rm -f Makefile
rm -f Makefile.{in,mingw,simple}
Added config.cygwin.








































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
####### Compiler, tools and options

CC	=	g++
CFLAGS	= -DWINDOZE -D_WIN32 -O0 -mno-cygwin -D__cplusplus	-Wall
-fstrength-reduce -D__WIN32__ -I/cygnus/cygwin-b20/include/g++ -I/cygnus/cygwin-b20/include/g++ -I/my/mysql_src/mysql-3.22.13-beta/include -L/my/mysql_src/mysql-3.22.13-beta/client/.libs -L../sqlplusint  -mno-cygwin
#CFLAGS +=	-fkeep-inline-functions
# If you have problems when with undefined refrences try uncommenting
# the above line when compiling the library.  But then recommenting 
# it when you compile the examples.  
FPIC    =#	-fPIC
INCPATH	=	 -I/cygnus/cygwin-b20/include/g++ -I/my/mysql_src/mysql-3.22.13-beta/include # make sure you can find mysql.h
LINK	=	g++
LFLAGS  = -mno-cygwin			# make sure you can find mysqlclinet
NLFLAGS =       -lmysql++       # this is for the static lib test
SLFLAGS	=	-lmysql++       # this is for shared lib test
LIBS	=	-lmysqlclient -mno-cygwin
SOLLIBS = 	-lnsl -lsocket	# extra lib that Solaris needs 
ARC	=	ar rc
CP_R    =       cp -a
RMDIR   =	echo
#RMDIR   =	rmdir 
#uncomment the above line if your sure your rmdir does NOT delete non-empty
#directories.  If it does make remove could be DISASTORIUS.
INSTLIB  =	/usr/lib
INSTHEAD =	/usr/include
INSTBIN  =      /usr/bin
PERLPATH =      /usr/bin/perl

#CFLAGS  +=	-D NO_LONG_LONGS

#TYPE    =	objs
TYPE	 =	static
#TYPE	=	shared

TARGET  =	linux
#TARGET	= 	solaris
##

# You should not need to modify anything below this line. If you do
# need to modify something below this line please email me at
# sinisa@cytanet.com.cy with what you did.

ifeq ($(TARGET), solaris)
  LIBS += $(SOLLIBS)
endif

OBJSINT = coldata.o connection.o datetime.o field_names.o field_types.o \
  manip.o query.o result.o row.o set.o sql_query.o type_info.o vallist.o

HEADERS = mysql++ mysql++.h mysql++-custom mysql++-custom.h

HEADSINT = mysql++ defs \
 define_short coldata1.hh \
 type_info1.hh const_string1.hh \
 null1.hh compare1.hh row1.hh \
 resiter1.hh vallist1.hh manip1.hh \
 sql_string1.hh sql_query1.hh \
 sql_query0.hh datetime1.hh \
 stream2string1.hh tiny_int1.hh \
 set1.hh connection1.hh query1.hh \
 result1.hh field_names1.hh \
 tracker.h field_types1.hh \
 fields1.hh connection0.hh \
 convert1.hh coldata2.hh \
 compare2.hh connection2.hh \
 query2.hh const_string2.hh \
 convert2.hh datetime2.hh \
 stream2string2.hh field_names2.hh \
 field_types2.hh fields2.hh \
 manip2.hh null2.hh result2.hh \
 row2.hh set2.hh stream2string3.hh \
 sql_query2.hh sql_string2.hh \
 tiny_int2.hh type_info2.hh \
 vallist2.hh coldata3.hh \
 convert3.hh null3.hh compare3.hh \
 connection3.hh const_string3.hh \
 datetime3.hh field_names3.hh \
 field_types3.hh manip3.hh \
 query3.hh result3.hh row3.hh \
 set3.hh sql_query3.hh \
 sql_string3.hh tiny_int3.hh \
 type_info3.hh vallist3.hh \
 custom.hh custom-macros.hh

####### Implicit rules

.SUFFIXES:

%.o: %.cc
	$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<

%.o: %.c
	$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<

%: %.o
ifeq ($(TYPE), objs)
	$(CC) $(CFLAGS) $(LIBS) -o $@ ../sqlplusint/*.o $^
endif
ifeq ($(TYPE), static)
	$(CC) $(CFLAGS) $(NLFLAGS) $(LIBS) -o $@ $^
endif
ifeq ($(TYPE), shared)
	$(CC) $(CFLAGS) $(SLFLAGS) $(LIBS) -o $@ $^
endif
Added config.h.in.




















































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* config.h.in.  Generated automatically from configure.in by autoheader.  */
/*
** This file has been automatically generated by 'acconfig' from aclocal.m4
** Copyright (C) 1988 Eleftherios Gkioulekas <lf@amath.washington.edu>
**  
** This file is free software; as a special exception the author gives
** unlimited permission to copy and/or distribute it, with or without 
** modifications, as long as this notice is preserved.
** 
** This program is distributed in the hope that it will be useful, but
** WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
** implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

/* This is the top section */


/* Define to empty if the keyword does not work.  */
#undef const

/* Define if you have the ANSI C header files.  */
#undef STDC_HEADERS

#undef SQLPLUS_MAJOR_VERSION
#undef SQLPLUS_MINOR_VERSION
#undef SQLPLUS_MICRO_VERSION
#undef SQLPLUS_INTERFACE_AGE
#undef SQLPLUS_BINARY_AGE

/* Define if you have the strtol function.  */
#undef HAVE_STRTOL

/* Define if you have the intl library (-lintl).  */
#undef HAVE_LIBINTL

/* Define if you have the nsl library (-lnsl).  */
#undef HAVE_LIBNSL

/* Define if you have the socket library (-lsocket).  */
#undef HAVE_LIBSOCKET

/* Name of package */
#undef PACKAGE

/* Version number of package */
#undef VERSION

/* Define if using the dmalloc debugging malloc package */
#undef WITH_DMALLOC

/* This is the bottom section */

Deleted config/acx_pthread.m4.
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









































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl This macro figures out how to build C programs using POSIX
dnl threads.  It sets the PTHREAD_LIBS output variable to the threads
dnl library and linker flags, and the PTHREAD_CFLAGS output variable
dnl to any special C compiler flags that are needed.  (The user can also
dnl force certain compiler flags/libs to be tested by setting these
dnl environment variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well.  e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
dnl
dnl If you are only building threads programs, you may wish to
dnl use these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl        LIBS="$PTHREAD_LIBS $LIBS"
dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl        CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE
dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands
dnl to run it if it is not found.  If ACTION-IF-FOUND is not specified,
dnl the default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform,
dnl or if you have any other suggestions or comments.  This macro was
dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org)
dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread
dnl macros posted by Alejandro Forero Cuervo to the autoconf macro
dnl repository.  We are also grateful for the helpful feedback of
dnl numerous users.
dnl
dnl @version $Id: acx_pthread.m4 1129 2005-10-04 17:53:10Z wyoung $
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>

AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no

# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.

# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
        save_CFLAGS="$CFLAGS"
        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
        save_LIBS="$LIBS"
        LIBS="$PTHREAD_LIBS $LIBS"
        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
        AC_MSG_RESULT($acx_pthread_ok)
        if test x"$acx_pthread_ok" = xno; then
                PTHREAD_LIBS=""
                PTHREAD_CFLAGS=""
        fi
        LIBS="$save_LIBS"
        CFLAGS="$save_CFLAGS"
fi

# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).

# Create a list of thread flags to try.  Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.

acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"

# The ordering *is* (sometimes) important.  Some notes on the
# individual items follow:

# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
#       other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
#      doesn't hurt to check since this sometimes defines pthreads too;
#      also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)

case "${host_cpu}-${host_os}" in
        *solaris*)

        # On Solaris (at least, for some versions), libc contains stubbed
        # (non-functional) versions of the pthreads routines, so link-based
        # tests will erroneously succeed.  (We need to link with -pthread or
        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
        # a function called by this macro, so we could check for that, but
        # who knows whether they'll stub that too in a future libc.)  So,
        # we'll just look for -pthreads and -lpthread first:

        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
        ;;
esac

if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do

        case $flag in
                none)
                AC_MSG_CHECKING([whether pthreads work without any flags])
                ;;

                -*)
                AC_MSG_CHECKING([whether pthreads work with $flag])
                PTHREAD_CFLAGS="$flag"
                ;;

		pthread-config)
		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
		if test x"$acx_pthread_config" = xno; then continue; fi
		PTHREAD_CFLAGS="`pthread-config --cflags`"
		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
		;;

                *)
                AC_MSG_CHECKING([for the pthreads library -l$flag])
                PTHREAD_LIBS="-l$flag"
                ;;
        esac

        save_LIBS="$LIBS"
        save_CFLAGS="$CFLAGS"
        LIBS="$PTHREAD_LIBS $LIBS"
        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"

        # Check for various functions.  We must include pthread.h,
        # since some functions may be macros.  (On the Sequent, we
        # need a special flag -Kthread to make this header compile.)
        # We check for pthread_join because it is in -lpthread on IRIX
        # while pthread_create is in libc.  We check for pthread_attr_init
        # due to DEC craziness with -lpthreads.  We check for
        # pthread_cleanup_push because it is one of the few pthread
        # functions on Solaris that doesn't have a non-functional libc stub.
        # We try pthread_create on general principles.
        AC_TRY_LINK([#include <pthread.h>],
                    [pthread_t th; pthread_join(th, 0);
                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
                    [acx_pthread_ok=yes])

        LIBS="$save_LIBS"
        CFLAGS="$save_CFLAGS"

        AC_MSG_RESULT($acx_pthread_ok)
        if test "x$acx_pthread_ok" = xyes; then
                break;
        fi

        PTHREAD_LIBS=""
        PTHREAD_CFLAGS=""
done
fi

# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
        save_LIBS="$LIBS"
        LIBS="$PTHREAD_LIBS $LIBS"
        save_CFLAGS="$CFLAGS"
        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"

        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
	AC_MSG_CHECKING([for joinable pthread attribute])
	attr_name=unknown
	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr;],
                        [attr_name=$attr; break])
	done
        AC_MSG_RESULT($attr_name)
        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
                               [Define to necessary symbol if this constant
                                uses a non-standard name on your system.])
        fi

        AC_MSG_CHECKING([if more special flags are required for pthreads])
        flag=no
        case "${host_cpu}-${host_os}" in
            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
        esac
        AC_MSG_RESULT(${flag})
        if test "x$flag" != xno; then
            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
        fi

        LIBS="$save_LIBS"
        CFLAGS="$save_CFLAGS"

        # More AIX lossage: must compile with cc_r
        AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
        PTHREAD_CC="$CC"
fi

AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)

# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
        :
else
        acx_pthread_ok=no
        $2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD
Deleted config/libm.m4.
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





































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis LIB_MATH
dnl 
dnl This macro figures out how whether programs using C's math routines
dnl need to link to libm or not.  This is common on SysV Unices.
dnl
dnl @category C
dnl @author Warren Young <warren@etr-usa.com>
dnl @version 1.2, 2006-03-06

AC_DEFUN([LIB_MATH],
[
	AC_MSG_CHECKING([whether -lm is needed to use C math functions])
	
	MYSQLPP_EXTRA_LIBS=
	TRY_LIBM=no
	AC_TRY_LINK(
		[ #include <math.h> ],
		[ floor(0); ], AC_MSG_RESULT(no), TRY_LIBM=yes)

	if test "x$TRY_LIBM" = "xyes"
	then
		save_LIBS=$LIBS
		LIBS="$LIBS -lm"
		AC_TRY_LINK(
			[ #include <math.h> ],
			[ floor(0); ],
			[ 
				MYSQLPP_EXTRA_LIBS=-lm 
				AC_MSG_RESULT(yes)
			],
			AC_MSG_ERROR([Failed to build program containing math functions!]))
		LIBS="$save_LIBS"
	fi

	AC_SUBST(MYSQLPP_EXTRA_LIBS)
])

Deleted config/localtime_r.m4.
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






























-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis AX_C_LOCALTIME_R
dnl 
dnl This macro determines whether the C runtime library contains
dnl localtime_r(), a thread-safe replacement for localtime().
dnl
dnl @version 1.0, 2007/02/20
dnl @author Warren Young <mysqlpp@etr-usa.com>
AC_DEFUN([AX_C_LOCALTIME_R],
[
	AC_MSG_CHECKING([for localtime_r()])

	AC_TRY_RUN([
		#include <time.h>
		int main(void)
		{
			time_t tt;
			struct tm stm;
			localtime_r(&tt, &stm);
			return 0;
		}
	], [localtime_r_found=yes], [localtime_r_found=no], [localtime_r_found=no])

	AC_MSG_RESULT([$localtime_r_found])
	if test x"$localtime_r_found" = xyes
	then
		AC_DEFINE(HAVE_LOCALTIME_R, 1,
			[Define if you have the localtime_r() facility])
	fi
]) dnl AX_C_LOCALTIME_R

Deleted config/mysql++.m4.
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



































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#-######################################################################
# mysql++.m4 - Example autoconf macro showing how to find MySQL++
#	library and header files.
#
# Copyright (c) 2004-2005 by Educational Technology Resources, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with MySQL++; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
#-######################################################################

dnl @synopsis MYSQLPP_DEVEL
dnl 
dnl This macro tries to find the MySQL++ library and header files.
dnl
dnl We define the following configure script flags:
dnl
dnl		--with-mysqlpp: Give prefix for both library and headers, and try
dnl			to guess subdirectory names for each.  (e.g. tack /lib and
dnl			/include onto given dir name, and other common schemes.)
dnl		--with-mysqlpp-lib: Similar to --with-mysqlpp, but for library only.
dnl		--with-mysqlpp-include: Similar to --with-mysqlpp, but for headers
dnl			only.
dnl
dnl This macro depends on having the default compiler and linker flags
dnl set up for building programs against the MySQL C API.  The mysql.m4
dnl macro in this directory fits this bill; run it first.
dnl
dnl @version 1.0, 2005/07/13
dnl @author Warren Young <mysqlpp@etr-usa.com>

AC_DEFUN([MYSQLPP_DEVEL],
[
AC_CACHE_CHECK([for MySQL++ devel stuff], ac_cv_mysqlpp_devel,
[
	#
	# Set up configure script macros
	#
	AC_ARG_WITH(mysqlpp,
		[  --with-mysqlpp=<path>     path containing MySQL++ header and library subdirs],
		[MYSQLPP_lib_check="$with_mysqlpp/lib $with_mysqlpp/lib/mysql++"
		  MYSQLPP_inc_check="$with_mysqlpp/include $with_mysqlpp/include/mysql++"],
		[MYSQLPP_lib_check="/usr/local/mysql++/lib /usr/local/lib/mysql++ /opt/mysql++/lib /usr/lib/mysql++ /usr/local/lib /usr/lib"
		  MYSQLPP_inc_check="/usr/local/mysql++/include /usr/local/include/mysql++ /opt/mysql++/include /usr/local/include/mysql++ /usr/local/include /usr/include/mysql++ /usr/include"])
	AC_ARG_WITH(mysqlpp-lib,
		[  --with-mysqlpp-lib=<path> directory path of MySQL++ library],
		[MYSQLPP_lib_check="$with_mysqlpp_lib $with_mysqlpp_lib/lib $with_mysqlpp_lib/lib/mysql"])
	AC_ARG_WITH(mysqlpp-include,
		[  --with-mysqlpp-include=<path> directory path of MySQL++ headers],
		[MYSQLPP_inc_check="$with_mysqlpp_include $with_mysqlpp_include/include $with_mysqlpp_include/include/mysql"])

	#
	# Look for MySQL++ library
	#
	MYSQLPP_libdir=
	for dir in $MYSQLPP_lib_check
	do
		if test -d "$dir" && \
			( test -f "$dir/libmysqlpp.so" ||
			  test -f "$dir/libmysqlpp.a" )
		then
			MYSQLPP_libdir=$dir
			break
		fi
	done

	if test -z "$MYSQLPP_libdir"
	then
		AC_MSG_ERROR([Didn't find the MySQL++ library dir in '$MYSQLPP_lib_check'])
	fi

	case "$MYSQLPP_libdir" in
		/* ) ;;
		* )  AC_MSG_ERROR([The MySQL++ library directory ($MYSQLPP_libdir) must be an absolute path.]) ;;
	esac

	AC_MSG_RESULT([lib in $MYSQLPP_libdir])

	case "$MYSQLPP_libdir" in
	  /usr/lib) ;;
	  *) LDFLAGS="$LDFLAGS -L${MYSQLPP_libdir}" ;;
	esac


	#
	# Look for MySQL++ headers
	#
	AC_MSG_CHECKING([for MySQL++ header directory])
	MYSQLPP_incdir=
	for dir in $MYSQLPP_inc_check
	do
		if test -d "$dir" && test -f "$dir/mysql++.h"
		then
			MYSQLPP_incdir=$dir
			break
		fi
	done

	if test -z "$MYSQLPP_incdir"
	then
		AC_MSG_ERROR([Didn't find the MySQL++ header dir in '$MYSQLPP_inc_check'])
	fi

	case "$MYSQLPP_incdir" in
		/* ) ;;
		* )  AC_MSG_ERROR([The MySQL++ header directory ($MYSQLPP_incdir) must be an absolute path.]) ;;
	esac

	AC_MSG_RESULT([$MYSQLPP_incdir])

	CPPFLAGS="$CPPFLAGS -I${MYSQLPP_incdir}"

	AC_MSG_CHECKING([that we can build MySQL++ programs])
	AC_COMPILE_IFELSE(
		[AC_LANG_PROGRAM([#include <mysql++.h>],
		[std::string s; mysqlpp::escape_string(s)])],
		ac_cv_mysqlpp_devel=yes,
		AC_MSG_ERROR(no))
])]) dnl End MYSQLPP_DEVEL

Deleted config/mysql_loc.m4.
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
















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis MYSQL_API_LOCATION
dnl 
dnl This macro tries to find MySQL C API header and library locations.
dnl
dnl We define the following configure script flags:
dnl
dnl		--with-mysql: Give prefix for both library and headers, and try
dnl			to guess subdirectory names for each.  (e.g. Tack /lib and
dnl			/include onto given dir name, and other common schemes.)
dnl		--with-mysql-lib: Similar to --with-mysql, but for library only.
dnl		--with-mysql-include: Similar to --with-mysql, but for headers
dnl			only.
dnl
dnl @version 1.2, 2007/02/20
dnl @author Warren Young <mysqlpp@etr-usa.com>
AC_DEFUN([MYSQL_API_LOCATION],
[
	#
	# Set up configure script macros
	#
	AC_ARG_WITH(mysql,
		[  --with-mysql=<path>     root directory path of MySQL installation],
		[MYSQL_lib_check="$with_mysql/lib/mysql $with_mysql/lib"
		MYSQL_inc_check="$with_mysql/include $with_mysql/include/mysql"],
		[MYSQL_lib_check="/usr/lib64 /usr/lib/x86_64-linux-gnu /usr/lib /usr/lib64/mysql /usr/lib/mysql /usr/local/lib64 /usr/local/lib /usr/local/lib/mysql /usr/local/mysql/lib /usr/local/mysql/lib/mysql /opt/mysql/lib /opt/mysql/lib/mysql"
		MYSQL_inc_check="/usr/include/mysql /usr/local/include/mysql /usr/local/mysql/include/mysql /opt/mysql/include/mysql"])
	AC_ARG_WITH(mysql-lib,
		[  --with-mysql-lib=<path> directory path of MySQL library installation],
		[MYSQL_lib_check="$with_mysql_lib $with_mysql_lib/lib64 $with_mysql_lib/lib $with_mysql_lib/lib64/mysql $with_mysql_lib/lib/mysql"])
	AC_ARG_WITH(mysql-include,
		[  --with-mysql-include=<path> directory path of MySQL header installation],
		[MYSQL_inc_check="$with_mysql_include $with_mysql_include/include $with_mysql_include/include/mysql"])

	#
	# Decide which C API library to use, based on thread support
	#
	if test "x$acx_pthread_ok" = xyes
	then
		MYSQL_C_LIB=mysqlclient_r
	else
		MYSQL_C_LIB=mysqlclient
	fi

	#
	# Look for MySQL C API library
	#
	AC_MSG_CHECKING([for MySQL library directory])
	MYSQL_libdir=
	for m in $MYSQL_lib_check
	do
		if test -d "$m" && \
			(test -f "$m/lib$MYSQL_C_LIB.so" || test -f "$m/lib$MYSQL_C_LIB.a")
		then
			MYSQL_libdir=$m
			break
		fi
	done

	if test -z "$MYSQL_libdir"
	then
		AC_MSG_ERROR([Didn't find $MYSQL_C_LIB library in '$MYSQL_lib_check'])
	fi

	case "$MYSQL_libdir" in
		/* ) ;;
		* )  AC_MSG_ERROR([The MySQL library directory ($MYSQL_libdir) must be an absolute path.]) ;;
	esac

	AC_MSG_RESULT([$MYSQL_libdir])

	case "$MYSQL_libdir" in
	  /usr/lib) ;;
	  *) LDFLAGS="$LDFLAGS -L${MYSQL_libdir}" ;;
	esac


	#
	# Look for MySQL C API headers
	#
	AC_MSG_CHECKING([for MySQL include directory])
	MYSQL_incdir=
	for m in $MYSQL_inc_check
	do
		if test -d "$m" && test -f "$m/mysql.h"
		then
			MYSQL_incdir=$m
			break
		fi
	done

	if test -z "$MYSQL_incdir"
	then
		AC_MSG_ERROR([Didn't find the MySQL include dir in '$MYSQL_inc_check'])
	fi

	case "$MYSQL_incdir" in
		/* ) ;;
		* )  AC_MSG_ERROR([The MySQL include directory ($MYSQL_incdir) must be an absolute path.]) ;;
	esac

	AC_MSG_RESULT([$MYSQL_incdir])

	CPPFLAGS="$CPPFLAGS -I${MYSQL_incdir}"

	save_LIBS=$LIBS
	LIBS="$LIBS $MYSQLPP_EXTRA_LIBS"
	AC_CHECK_LIB($MYSQL_C_LIB, mysql_store_result, [], [
			AC_MSG_ERROR([Could not find working MySQL client library!]) ])
	AC_SUBST(MYSQL_C_LIB)
	LIBS=$save_LIBS
]) dnl MYSQL_API_LOCATION

Deleted config/mysql_ssl.m4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis MYSQL_WITH_SSL
dnl
dnl This macro determines whether mysql_ssl_set() API call exists.
dnl Requires at least MySQL 4.0.1. 
dnl 
dnl @version $Id$, $Date$
dnl @author Ovidiu Bivolaru <ovidiu@targujiu.rdsnet.ro>
AC_DEFUN([MYSQL_WITH_SSL],
[
    #
    # Check for mysql_ssl_set() in libmysqlclient(_r)
    #
    AC_CHECK_LIB($MYSQL_C_LIB, mysql_ssl_set, [
	AC_DEFINE(HAVE_MYSQL_SSL_SET,, Define if your MySQL library has SSL functions)
    ]) dnl AC_CHECK_LIB(mysqlclient, mysql_ssl_set)
]) dnl  MYSQL_WITH_SSL

Deleted config/socket_nsl.m4.
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








































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis LIB_SOCKET_NSL
dnl 
dnl This macro figures out what libraries are required on this platform
dnl to link sockets programs.
dnl
dnl The common cases are not to need any extra libraries, or to need
dnl -lsocket and -lnsl.  We need to avoid linking with libnsl unless
dnl we need it, though, since on some OSes where it isn't necessary it
dnl will totally break networking.  Unisys also includes gethostbyname()
dnl in libsocket but needs libnsl for socket().
dnl
dnl @category Misc
dnl @author Warren Young <mysqlpp@etr-usa.com>
dnl @version 1.5, 2006-03-06

AC_DEFUN([LIB_SOCKET_NSL],
[
	save_LIBS="$LIBS"

	AC_MSG_CHECKING([whether -lsocket is needed])
	TRY_LSOCKET=no
	AC_TRY_LINK(
		[ 
			#include <sys/types.h>
			#include <sys/socket.h> 
			#include <netinet/in.h>
			#include <arpa/inet.h>
		],
		[ socket(AF_INET, SOCK_STREAM, 0); ],
		AC_MSG_RESULT(no), TRY_LSOCKET=yes)

	if test "x$TRY_LSOCKET" = "xyes"
	then
		LIBS="-lsocket $LIBS"
		AC_TRY_LINK(
			[ 
				#include <sys/types.h>
				#include <sys/socket.h> 
				#include <netinet/in.h>
				#include <arpa/inet.h>
			],
			[ socket(AF_INET, SOCK_STREAM, 0); ],
			[ 
				MYSQLPP_EXTRA_LIBS="-lsocket $MYSQLPP_EXTRA_LIBS"
				AC_MSG_RESULT(yes)
			],
			AC_MSG_ERROR([failed to link using -lsocket!]))
	fi

	AC_MSG_CHECKING([whether -lnsl is needed])
	TRY_LNSL=no
	AC_TRY_LINK(
		[ #include <netdb.h> ],
		[ gethostbyname("gna.org"); ],
		AC_MSG_RESULT(no), TRY_LNSL=yes)

	if test "x$TRY_LNSL" = "xyes"
	then
		LIBS="-lnsl $LIBS"
		AC_TRY_LINK(
			[ #include <netdb.h> ],
			[ gethostbyname("gna.org"); ],
			[ 
				MYSQLPP_EXTRA_LIBS="-lnsl $MYSQLPP_EXTRA_LIBS"
				AC_MSG_RESULT(yes)
			],
			AC_MSG_ERROR([failed to link using -lnsl!]))
	fi

	AC_SUBST(MYSQLPP_EXTRA_LIBS)
])

Deleted config/stl_slist.m4.
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























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
dnl @synopsis STL_SLIST_EXTENSION
dnl 
dnl This macro determines whether the local STL implementation includes
dnl a singly-linked list template, slist, and if so, where it is.
dnl
dnl @version 1.2, 2005/07/22
dnl @author Warren Young <mysqlpp@etr-usa.com>
AC_DEFUN([STL_SLIST_EXTENSION],
[
	AC_MSG_CHECKING([for STL slist extension])

	AC_COMPILE_IFELSE(
		[AC_LANG_PROGRAM(
			[#include <slist>],
			[slist<int> l])],
		AC_DEFINE(HAVE_GLOBAL_SLIST, 1,
			[ Define if you have ::slist container in <slist> ]),
		TRY_NEXT=yes)

	if test -z "$TRY_NEXT"
	then
		SLIST_LOC="<slist>, global scope"
	else
		TRY_NEXT=""
		AC_COMPILE_IFELSE(
			[AC_LANG_PROGRAM(
				[#include <slist>],
				[std::slist<int> l])],
			AC_DEFINE(HAVE_STD_SLIST, 1,
				[ Define if you have std::slist container in <slist> ]),
			TRY_NEXT=yes)

		if test -z "$TRY_NEXT"
		then
			SLIST_LOC="<slist>, namespace std"
		else
			TRY_NEXT=""
			AC_COMPILE_IFELSE(
				[AC_LANG_PROGRAM(
					[#include <ext/slist>],
					[__gnu_cxx::slist<int> l])],
				AC_DEFINE(HAVE_EXT_SLIST, 1,
					[ Define if you have __gnu_cxx:slist container in <ext/slist> ]),
				SLIST_LOC="not found")

			if test -z "$SLIST_LOC"
			then
				SLIST_LOC="<ext/slist>, namespace __gnu_cxx"
			fi
		fi
	fi

	AC_MSG_RESULT([$SLIST_LOC])
]) dnl STL_SLIST_EXTENSION

Deleted configure.ac.
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





















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with MySQL++; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA

# Standard autotools stuff
AC_INIT(mysql++, 2.3.2, plusplus@lists.mysql.com, mysql++)
AC_CONFIG_HEADER(config.h)
AC_DISABLE_STATIC
AC_CANONICAL_SYSTEM
AC_PROG_CC
AC_PROG_CXX


# Break package version up into major, minor and bugfix components.
MYSQLPP_VERSION_MAJOR=`echo $PACKAGE_VERSION | cut -f1 -d.`
AC_SUBST(MYSQLPP_VERSION_MAJOR)
MYSQLPP_VERSION_MINOR=`echo $PACKAGE_VERSION | cut -f2 -d.`
AC_SUBST(MYSQLPP_VERSION_MINOR)
MYSQLPP_VERSION_BUGFIX=`echo $PACKAGE_VERSION | cut -f3 -d.`
AC_SUBST(MYSQLPP_VERSION_BUGFIX)


# Include Bakefile macros
AC_BAKEFILE([m4_include(config/autoconf_inc.m4)])


# Check for Standard C support
AC_HEADER_STDC


# Figure out whether/how to handle threading support, if available.
AC_ARG_ENABLE(thread-check,
		[  --enable-thread-check  Check for threads, and use if available. ],
		[ thread_check=yes ])
if test "x$thread_check" = "xyes"
then
	ACX_PTHREAD
	LIBS="$PTHREAD_LIBS $LIBS"
	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
	CC="$PTHREAD_CC"
fi


# Checks for libraries and local system features
AC_CHECK_HEADERS(zlib.h, AC_CHECK_LIB(z, gzread, [],
		[ AC_MSG_ERROR([zlib is required]) ]))
LIB_MATH
LIB_SOCKET_NSL
MYSQL_API_LOCATION
MYSQL_WITH_SSL
AX_C_LOCALTIME_R
AC_CHECK_LIB(intl, main)


# If this is Cygwin, add a linker flag to suppress a silly link message.
case "${host}" in
	*cygwin*)
		LDFLAGS="$LDFLAGS -Wl,--enable-auto-import"
		;;
esac


# Check for Standard C++ support, and extensions.  This must be near
# the end, because the CPLUSPLUS directive makes autoconf use C++
# compiler for all subsequent tests!
AC_LANG_CPLUSPLUS
STL_SLIST_EXTENSION


#
# Configure process complete; write out files generated from *.in.
#
AC_OUTPUT([Makefile mysql++.spec lib/Doxyfile lib/mysql++.h])

Added configure.in.




















































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
dnl Process this file with autoconf to produce a configure script.
# require autoconf 2.13
AC_PREREQ(2.13)

AC_INIT(sqlplusint/sqlplus.hh)

dnl Much of this was copied from glib's configure.in

dnl we need to AC_DIVERT_PUSH/AC_DIVERT_POP these variable definitions so they
dnl are available for $ac_help expansion (don't we all *love* autoconf?)
AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
#
# Making releases:
#   SQLPLUS_MICRO_VERSION += 1;
#   SQLPLUS_INTERFACE_AGE += 1;
#   SQLPLUS_BINARY_AGE += 1;
# if any functions have been added, set SQLPLUS_INTERFACE_AGE to 0.
# if backwards compatibility has been broken,
# set SQLPLUS_BINARY_AGE _and_ SQLPLUS_INTERFACE_AGE to 0.
#

SQLPLUS_MAJOR_VERSION=1
SQLPLUS_MINOR_VERSION=5
SQLPLUS_MICRO_VERSION=0
SQLPLUS_INTERFACE_AGE=0
SQLPLUS_BINARY_AGE=0

SQLPLUS_VERSION=$SQLPLUS_MAJOR_VERSION.$SQLPLUS_MINOR_VERSION.$SQLPLUS_MICRO_VERSION
dnl
AC_DIVERT_POP()dnl

VERSION=$SQLPLUS_VERSION

AC_SUBST(SQLPLUS_MAJOR_VERSION)
AC_SUBST(SQLPLUS_MINOR_VERSION)
AC_SUBST(SQLPLUS_MICRO_VERSION)
AC_SUBST(SQLPLUS_INTERFACE_AGE)
AC_SUBST(SQLPLUS_BINARY_AGE)

# libtool versioning
LT_RELEASE=$SQLPLUS_MAJOR_VERSION.$SQLPLUS_MINOR_VERSION
LT_CURRENT=`expr $SQLPLUS_MICRO_VERSION - $SQLPLUS_INTERFACE_AGE`
LT_REVISION=$SQLPLUS_INTERFACE_AGE
LT_AGE=`expr $SQLPLUS_BINARY_AGE - $SQLPLUS_INTERFACE_AGE`
AC_SUBST(LT_RELEASE)
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)

dnl Initialize automake
AM_INIT_AUTOMAKE(sqlplus, $VERSION)

dnl Set definition here
AM_CONFIG_HEADER(config.h)

dnl Initialize libtool
AM_PROG_LIBTOOL

dnl Initialize maintainer mode
AM_MAINTAINER_MODE

dnl This is a little hack to make this work with rpm better (see sqlplus.spec.in)
test -z "$CXXFLAGS" && CXXFLAGS="${CFLAGS}"

dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AC_PROG_CXXCPP

dnl Copied from lf_texidoc.m4 in share/aclocal
AC_PATH_PROGS(PERL, perl perl5, nope)
if test "$PERL" = nope 
then
   AC_MSG_WARN([missing perl. Need perl to build documentation and some headers which should have been included in the distribution.])
fi


AC_PROG_LN_S
AC_PROG_INSTALL
AC_PROG_MAKE_SET

dnl These will be set in config.h
AC_DEFINE_UNQUOTED(SQLPLUS_MAJOR_VERSION, $SQLPLUS_MAJOR_VERSION)
AC_DEFINE_UNQUOTED(SQLPLUS_MINOR_VERSION, $SQLPLUS_MINOR_VERSION)
AC_DEFINE_UNQUOTED(SQLPLUS_MICRO_VERSION, $SQLPLUS_MICRO_VERSION)
AC_DEFINE_UNQUOTED(SQLPLUS_INTERFACE_AGE, $SQLPLUS_INTERFACE_AGE)
AC_DEFINE_UNQUOTED(SQLPLUS_BINARY_AGE,    $SQLPLUS_BINARY_AGE)

AC_CHECK_LIB(intl, main)
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)

dnl #########################################################################
dnl Check for MySQL headers and libraries
dnl #########################################################################
AC_PACKAGE_MYSQL

AM_WITH_DMALLOC()

dnl Checks for header files.
AC_HEADER_STDC

dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST

dnl Checks for library functions.
AC_CHECK_FUNCS(strtol)

AC_OUTPUT([
Makefile
sqlplusint/Makefile
examples/Makefile
doc/Makefile
sqlplus-config
sqlplus.spec
])
Added doc/Makefile.am.








































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# This file should cause the manual to be a generated source (i.e., so
# that it is build at distribution time since its creation is
# non-standard) 

# This file still needs a lot of work...

# SUBDIRS = man-html man-text

EXTRA_DIST = \
  doc.tex.tmpl html.sty manual.aux manual.dvi manual.log manual.lyx \
  manual.ps manual.tex pretty.pl sql++pretty doc-fix.pl doc-trim.pl \
  examples-proc.pl html2txt.pl insert-classref.pl

default: manual

perlclean: 
	-rm -f manual.txt manual.html
	$(MAKE) -C ../sqlplusint/ perlclean

manual:
	$(MAKE) -C ../sqlplusint/  classref
	perl insert-classref.pl
	-rm -f -r man-html
	-mkdir man-html
	perl examples-proc.pl
	latex manual.tex
	latex manual.tex
	latex2html \
	  -split 3 \
	  -toc_depth 3 \
	  -dir man-html \
	  -long_titles 2 \
	  -local_icons \
	  -show_section_numbers \
	   manual.tex

	-rm -f -r man-text
	-mkdir man-text
	perl html2txt.pl

Deleted doc/README.devel.
1
2
3
4
5
6
7
8
9
10
11











-
-
-
-
-
-
-
-
-
-
-
This file comes with the mysql++-devel RPM.  This RPM installs the
files you need when building your own MySQL++ based programs, as well as
documentation and examples that can help you learn how to use the library.
The documentation is pretty badly out of date at the moment.  See the
example programs for the "official" word on how to use this library.

This RPM installs the MySQL++ header files in /usr/include/mysql++,
the MySQL++ library in /usr/lib, and a set of example programs in
/usr/src/mysql++/examples.  For more information on the examples, see
the README.examples file in this directory.

Deleted doc/README.manuals.
1
2
3
4
5





-
-
-
-
-
For more information about MySQL++, see its home page:

	http://tangentsoft.net/mysql++/

See the LICENSE file in this directory for the library's license.
Added doc/doc-fix.pl.






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$/ = undef;

open F, $ARGV[0];

$_=<F>;

s~\\begin_inset LatexCommand \\ref.+
\\end_inset
(.+)
\\begin_inset LatexDel .+
\\end_inset
.+
\\begin_inset LatexDel .+
\\end_inset
~\\begin_inset LatexCommand \\ref\{$1\}

\\end_inset
~g;

open F, ">$ARGV[0]";
print F $_;

Added doc/doc-trim.pl.











1
2
3
4
5
6
7
8
9
10
11
+
+
+
+
+
+
+
+
+
+
+
$/ = undef;

open F, $ARGV[0];

$_=<F>;

/(\\layout Section.+)\\the_end/s;

open F, ">$ARGV[0]";
print F $1;

Added doc/doc.tex.tmpl.

































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ptags [ ]
[!autolink]

[foreach class]
\section{[class]}
\label{[filter ref][class dont_filter][endfilter]}

[if templ]template [endif] \
[if struct]struct[endif][else][if union]union[endif][else]class[endelse][endelse] \
\textbf{[class]}[templ]

[if parents]\textbf{Parents:} [parents][endif]

[if with_class][if with_class != [class]]
  \textbf{Related to:} [with_class] \
  (\ref{[filter ref][with_class dont_filter][endfilter]})
[endif][endif]

[if brief]\textit{[brief]}[endif]

[detail]

\subsection{Synopses}

[if public]
\textbf{Public members:}
\begin{itemize}
[foreach public]
\item [if pure]pure [endif][type] \textbf{[mname]} \
  [if func] \
    ([args]) [if const] const [endif] \
    [if throws] throws [throwclass]([throwargs])[endif] \
  [endif] \
  [if enum] [lb][args][rb] [endif] \
  [if detail] (\ref{[filter ref][class dont_filter]::[member dont_filter][endfilter]}) [endif] \
  [if brief] - \textit{[brief]}[endif] \
[next]

\end{itemize}
[endif]

[if protected]
\textbf{Protected members:}
\begin{itemize}

[foreach protected]
\item [if pure]pure [endif][type] \textbf{[mname]} \
  [if func] \
    ([args]) [if const] const [endif] \
    [if throws] throws [throwclass]([throwargs])[endif] \
  [endif] \
  [if enum] [lb][args][rb] [endif] \
  [if detail] (\ref{[filter ref][class dont_filter]::[member dont_filter][endfilter]}) [endif] \
  [if brief] - \textit{[brief]}[endif] \
[next]

\end{itemize}
[endif]

[nobreak]
[foreach func]
[if with_class == [class]]
[if !l1][def l1]
    \textbf{Related Functions} [n]
    [n]
    \begin{itemize} [n]
[endif]
\item [type] \textbf{[name]} ([args]) 
    [if throws] throws [throwclass]([throwargs]) [endif] 
    [if brief] -  \textit{[brief]}[endif] [n]
[endif]
[next]
[if l1] [undef l1]
  \end{itemize} [n]
[endif]
[endnobreak]

[nobreak]
[foreach typedef]
[if with_class == [class]]
  [if !l1] [def l1]
    \textbf{Related Types} [n]
    [n]
    \begin{itemize} [n]
  [endif]
\item [if typedef]typedef [endif][if enum]enum [endif][type] \textbf{[name]}
  [if enum] [lb][args][rb] [endif]
  [if brief] - \textit{[brief]}[endif] [n]
[endif]
[next]
[if l1] [undef l1]
  \end{itemize} [n]
[endif]
[endnobreak]

[nobreak]
[def pclass [class]]
[foreach class]
[if with_class == [pclass]] [if with_class != [class]]
[if !l1] [def l1]	
  \textbf{Related Classes} [n]
  [n]
  \begin{itemize} [n]
[endif]
\item [if templ]template [endif] 
  [if struct]struct[endif][else][if union]union[endif][else]class[endelse][endelse] 
    \textbf{[class]}[templ] 
    (\ref{[filter ref][class dont_escape][endfilter]}) 
    [if brief] - \textit{[brief]} [endif] [n]
[endif] [endif]
[next]
[if l1] [undef l1]
  \end{itemize} [n]
[endif]
[undef pclass]
[endnobreak]

[foreach public]
[if detail]
\subsection{[member]}
\label{[filter ref][class dont_filter]::[member dont_filter][endfilter]}

  [if pure]pure [endif][type] \textbf{[mname]} \
  [if func] \
    ([args]) [if const] const [endif] \
    [if throws] throws [throwclass]([throwargs])[endif] \
  [endif] \
  [if enum] [lb][args][rb] [endif]

[if brief]\textit{[brief]}[endif]

[detail]

[endif]

[next]

[foreach func][if with_class == [class]][// ][if detail]
\subsection{[name]}

[type] \textbf{[name]} ([args]) \
  [if throws] throws [throwclass]([throwargs]) [endif]

[if brief]\textit{[brief]}[endif]

[detail]

[endif][endif][next]

[next]


\section{Misc Non Members}

[foreach func][if !with_class]
[if !f1] [def f1]
  \textbf{Functions:}
  \begin{itemize}
[endif]
\item [type] \textbf{[name]} ([args]) \
  [if throws] throws [throwclass]([throwargs]) [endif] \
  [if brief] -  \textit{[brief]}[endif] 
[endif][next]
[if f1] [undef f1]
\end{itemize}
[endif]

[foreach typedef][if !with_class]
[if !tl] [def tl]
  \textbf{Types:}
  \begin{itemize}
[endif]
\item [if typedef]typedef [endif][if enum]enum [endif][type] \textbf{[name]}
  [if enum] [lb][args][rb] [endif]
  [if brief] - \textit{[brief]}[endif]
[endif][next]
[if tl] [undef tl]
\end{itemize}
[endif]

[foreach func]
[if detail][if !with_class]
\subsection{[name]}

[type] \textbf{[name]} ([args]) \
  [if throws] throws [throwclass]([throwargs]) [endif]

[if brief]\textit{[brief]}[endif]

[detail]

[endif][endif]
[next]
Added doc/examples-proc.pl.




















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

$/ = undef;
open IN, "manual.tex";
$_ = <IN>;

s/\\begin\{comment\}[\n\s]+example:(\S+)[\n\s]*\\end\{comment\}[\n\s]*/${\(&ie($1))}/sg;

open IN, ">manual.tex";
print IN;

sub ie {
  my $return;
  $return  = "\n";
  $return .= "\\begin{verbatim}\n";
  open EIN, "examples/$_[0]";
  local $/ = undef;
  $return .= <EIN>;
  $return .= "\\end{verbatim}\n\n";
  return $return;
}
Added doc/html2txt.pl.







1
2
3
4
5
6
7
+
+
+
+
+
+
+
opendir DIR, "man-html";

foreach (readdir(DIR)) {
  next unless /(.+?)\.html$/;
  print "lynx -dump man-html/$_ > man-text/$1.txt\n" ;
  system "lynx -dump man-html/$_ > man-text/$1.txt" ;
}
Added doc/insert-classref.pl.






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$/ = undef;

open F, "manual.tex";
open CR, "../sqlplusint/doc.tex";

$_=<F>;
$classref=<CR>;

s~\\begin{comment}[\s\n]*Begin Class Ref[\s\n]*\\end{comment}.+?\\begin{comment}[\s\n]*End Class Ref[\s\n]*\\end{comment}~
\\begin{comment}
Begin Class Ref
\\end{comment}
$classref
\\begin{comment}
End Class Ref
\\end{comment}
~s || die "Could not insert classref\n";

open F, ">manual.tex";
print F $_; 


Added doc/manual.lyx.

more than 10,000 changes

Added doc/pretty.pl.











































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
use FileHandle;
use IPC::Open2;

if ($ARGV[0] =~ /^--command\=(.+)/) {
    $command = $1;
} else {
    $command = "g++ -E";
}

$/ = undef;
$orgcode = <STDIN>;

($macro) = $orgcode =~ /(sql_create_.+? *\(.+?\))/s;

$out = << "---";

#include <sqlplusint/custom-macros.hh>

$macro

---

$/ = "\n";

$temp_dir = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};

#print $out;

open OUT, ">$temp_dir/${$}.cc";
print OUT $out;
close OUT;

system "$command $temp_dir/${$}.cc > $temp_dir/${$}.ii";

open IN, "$temp_dir/${$}.ii";
while (<IN>) {
    next if /^\#/;    
    $code .= $_;
}
close IN;

unlink "$temp_dir/${$}.cc","$temp_dir/${$}.ii";

$_ = $code;
s/\s+/ /g;
s/ *public: */public:\n/g;
s/ *private: */public:\n/g;
s/ *\; */\;\n/g;
s/ *\{ */ \{\n/g;
s/ *\} */ \}\n\n/g;
s/ *\n */\n/g;
s/\{\s+}/\{\}/g;
s/\}\s+\;/\}\;\n/g;

$code = "";
foreach (split /\n/) {
    if (/\}/ && !/\{\}/ ) {
	$indent -= 2;
	$ind = ' 'x$indent;
    }
    $code .= "$ind$_\n" unless /\:$/;
    $code .= "$_\n"     if     /\:$/;
    if (/\{/ && !/\{\}/ ) {
	$indent += 2;
	$ind = ' 'x$indent;
    } 
}

$orgcode =~ s/(sql_create_.+? *\(.+?\))/\n$code\n/s;

print $orgcode;




Added doc/sql++pretty.











































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
use FileHandle;
use IPC::Open2;

if ($ARGV[0] =~ /^--command\=(.+)/) {
    $command = $1;
} else {
    $command = "g++ -E";
}

$/ = undef;
$orgcode = <STDIN>;

($macro) = $orgcode =~ /(sql_create_.+? *\(.+?\))/s;

$out = << "---";

#include <sqlplusint/custom-macros.hh>

$macro

---

$/ = "\n";

$temp_dir = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};

#print $out;

open OUT, ">$temp_dir/${$}.cc";
print OUT $out;
close OUT;

system "$command $temp_dir/${$}.cc > $temp_dir/${$}.ii";

open IN, "$temp_dir/${$}.ii";
while (<IN>) {
    next if /^\#/;    
    $code .= $_;
}
close IN;

unlink "$temp_dir/${$}.cc","$temp_dir/${$}.ii";

$_ = $code;
s/\s+/ /g;
s/ *public: */public:\n/g;
s/ *private: */public:\n/g;
s/ *\; */\;\n/g;
s/ *\{ */ \{\n/g;
s/ *\} */ \}\n\n/g;
s/ *\n */\n/g;
s/\{\s+}/\{\}/g;
s/\}\s+\;/\}\;\n/g;

$code = "";
foreach (split /\n/) {
    if (/\}/ && !/\{\}/ ) {
	$indent -= 2;
	$ind = ' 'x$indent;
    }
    $code .= "$ind$_\n" unless /\:$/;
    $code .= "$_\n"     if     /\:$/;
    if (/\{/ && !/\{\}/ ) {
	$indent += 2;
	$ind = ' 'x$indent;
    } 
}

$orgcode =~ s/(sql_create_.+? *\(.+?\))/\n$code\n/s;

print $orgcode;




Deleted doc/ssqls-pretty.
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



















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/usr/bin/perl
use FileHandle;
use IPC::Open2;

if ($ARGV[0] =~ /^--command\=(.+)/) {
    $command = $1;
} else {
    $command = "g++ -E";
}

if (-e 'lib/mysql++.h') {
	$command .= " -I lib";
}
else {
	$command .= " -I /usr/include/mysql++/";
}

$/ = undef;
$orgcode = <STDIN>;

($macro) = $orgcode =~ /(sql_create_.+? *\(.+?\))/s;

$out = << "---";

#include <custom-macros.h>

$macro

---

$/ = "\n";

$temp_dir = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};

#print $out;

open OUT, ">$temp_dir/${$}.cc";
print OUT $out;
close OUT;

system "$command $temp_dir/${$}.cc > $temp_dir/${$}.ii";

open IN, "$temp_dir/${$}.ii";
while (<IN>) {
    next if /^\#/;    
    $code .= $_;
}
close IN;

unlink "$temp_dir/${$}.cc","$temp_dir/${$}.ii";

$_ = $code;
s/\s+/ /g;
s/ *public: */public:\n/g;
s/ *private: */public:\n/g;
s/ *\; */\;\n/g;
s/ *\{ */ \{\n/g;
s/ *\} */ \}\n\n/g;
s/ *\n */\n/g;
s/\{\s+}/\{\}/g;
s/\}\s+\;/\}\;\n/g;

$code = "";
foreach (split /\n/) {
    if (/\}/ && !/\{\}/ ) {
	$indent -= 2;
	$ind = ' 'x$indent;
    }
    $code .= "$ind$_\n" unless /\:$/;
    $code .= "$_\n"     if     /\:$/;
    if (/\{/ && !/\{\}/ ) {
	$indent += 2;
	$ind = ' 'x$indent;
    } 
}

$orgcode =~ s/(sql_create_.+? *\(.+?\))/\n$code\n/s;

print $orgcode;




Deleted doc/userman/LICENSE.
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



























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
MySQL++ User Manual License
~~~~~~~~~~~~~~~~~~~~~~~~~~~

I. COPYRIGHT

    The copyright to the MySQL++ User Manual is owned by its authors.


II. LICENSE

    The MySQL++ User Manual may be reproduced and distributed in whole
    or in part, in any medium physical or electronic, provided that
    this license notice is displayed in the reproduction. Commercial
    redistribution is permitted and encouraged. Thirty days advance
    notice via email to the authors of redistribution is appreciated,
    to give the authors time to provide updated documents.


    A. REQUIREMENTS OF MODIFIED WORKS

        All modified documents, including translations,
        anthologies, and partial documents, must meet the
        following requirements:

            1.  The modified version must be labeled as such.

            2.  The person making the modifications must be
                identified.

            3.  Acknowledgement of the original author must be
                retained.

            4.  The location of the original unmodified
                document be identified.

            5.  The original authors' names may not be used
                to assert or imply endorsement of the
                resulting document without the original
                authors' permission.

        In addition it is requested that:

            1.  The modifications (including deletions)
                be noted.

            2.  The authors be notified by email of the
                modification in advance of redistribution,
                if an email address is provided in
                the document.

        Mere aggregation of the MySQL++ User Manual with other
        documents or programs on the same media shall not cause
        this license to apply to those other works.

        All translations, derivative documents, or modified
        documents that incorporate the MySQL++ User Manual may
        not have more restrictive license terms than these,
        except that you may require distributors to make the
        resulting document available in source format.
Deleted doc/userman/Makefile.
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





































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
## ------------------------
## Things you may need to diddle for your local system
## ------------------------

FOPDIR=/usr/local/fop


## ------------------------
## Input files
## ------------------------

HTML_DIR=../html/userman
BASENAME=userman
DOCFILE=$(BASENAME).dbx
PDFFILE=$(BASENAME).pdf
FOFILE=$(BASENAME).fo
COMMON_SS=common.xsl
FO_SS=fo.xsl
HTML_SS=html.xsl
EX_TXT=cgi_jpeg.txt custom1.txt custom2.txt custom3.txt custom4.txt \
		custom5.txt custom6.txt fieldinf1.txt for_each.txt load_jpeg.txt \
		resetdb.txt simple1.txt simple2.txt simple3.txt stock.txt \
		store_if.txt tquery.txt xaction.txt


## ------------------------
## Major output rules
## ------------------------

html: $(HTML_DIR)/index.html

pdf: $(PDFFILE)


## ------------------------
## Standard Makefile targets
## ------------------------

# Notice that this is not the first target in the file, as is standard.
# PDF generation takes longer than HTML generation, so to keep the code-
# test-debug-rebuild cycle short, we generate only the HTML manual by
# default.  You can explicitly say "make pdf" or "make all" when you're
# sure the DocBook file's contents are correct.
all: html pdf

clean:
	rm -f tags *.fo $(HTML_DIR)/*.html *.log *.out *.pdf *.txt


## ------------------------
## How to make output files
## ------------------------

$(PDFFILE): $(DOCFILE) $(FO_SS) $(COMMON_SS)
	xsltproc --xinclude $(FO_SS) $(DOCFILE) > $(FOFILE)
	$(FOPDIR)/fop -q -fo $(FOFILE) $(PDFFILE)
	cp $(PDFFILE) ../pdf

$(HTML_DIR)/index.html: $(DOCFILE) $(EX_TXT) $(HTML_SS) $(COMMON_SS)
	@xmllint --xinclude --postvalid --noent --noout $(DOCFILE)
	xsltproc --xinclude -o $(HTML_DIR)/ $(HTML_SS) $(DOCFILE)


## ------------------------
## Dependency rules
## ------------------------

$(EX_TXT):
	@./mktxt $@
Deleted doc/userman/README.
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
































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
The user manual is written in XML DocBook format, version 4.2.
It uses the official DocBook XSL stylesheets, and will build with
versions as old as 1.58.1.  (Why these versions?  They're what comes
with Red Hat Linux 9, the oldest system I still use.)  We restrict
ourselves to Simplified DocBook 1.1 as much as practical, to make it
easier for new people to get started hacking on the manual.

To make the HTML version of the user manual, just type 'make' in this
directory.  (Or 'make html' if you want to be pedantic.)  To make the
PDF version of the manual, say 'make pdf'.  To make both versions,
say 'make all'.



The most likely cause of build failures is not having the right
processing programs installed.  The DocBook processing model looks
like this:

    DocBook --[XSLT proc.]-+-> HTML
                   ^       |
                   |       +-> XSL-FO --[XSL-FO proc.]--> PDF
                   |
           {XSL stylesheets}

"DocBook" above is a file in DocBook XML format.  In this case,
it's in userman.dbx.

There are many alternatives for the tools in the square brackets:

	The first replaceable piece is an XSLT processor, which
	translates XML into other text formats, such as HTML or other
	varieties of XML.  We use xsltproc from the Gnome project.
	(http://xmlsoft.org/XSLT/)  There are numerous alternatives,
	but each supports different extensions to the standard,
	so it's simplest if everyone uses the same processor for a
	given document.

	We use the XSLT processor to do two transforms.  One is
	directly to HTML.  The other is to XSL-FO, an XML-based page
	layout language.  We do this intermediary transform because
	XSLT is not good at creating binary formats like PDF.

	The second replaceable piece in the diagram above is an
	XSL-FO processor, which converts XSL-FO to a more directly
	useful page layout format, like PDF.  We've chosen FOP from
	the Apache Project (http://xml.apache.org/fop/), because it's
	the best of the free-as-in-freedom XSL-FO processors.

	FOP isn't without its faults.  If you'd like to try some of
	the commercial XSL-FO processors, RenderX's XEP (renderx.com)
	is avalable in a free-as-in-beer version that adds watermarks
	to your pages.	Another popular option is Antenna House's XSL
	Formatter (antennahouse.com), but there is no free offering.
	The low-end commercial version of each of these is around $300.
	Another relatively inexpensive option is Lunasil's Xinc
	(lunasil.com), which is available in a personal-use edition
	for under $100.

The third replaceable piece above is the DocBook XSL stylesheet set.
The stylesheets are the XSLT processor's rules, controlling how
the input XML gets transformed to the output format.  The standard
DocBook stylesheet set (link below) includes stylesheets for HTML
and XSL-FO output.  If you don't have them on your system, the XSLT
processor will try to download them using your Internet connection
during processing.  This slows processing quite a bit even if you
have a fast Internet connection, and it obviously doesn't work when
your net connection is down.

A better option is to have a copy of the stylesheets on your system.
It's likely that there is a pre-built package for your system:

	Red Hat Linux: docbook-style-xsl RPM (same for Fedora Core)
	Mac OS X:      docbook-xsl Fink package (http://fink.sf.net)
	Cygwin:        docbook-xml?? package (?? = DocBook version)

(Please send the name of the package for your system to the mailing
list if it isn't listed above, and I'll add it to the list.)

If you can't find a package for your system, you can get the DocBook
stylesheets from the source: http://docbook.sourceforge.net/  They're
a bit tricky to set up correctly, so it's better to use a pre-built
package if you can.

If you are still having problems, post the details about it to the
MySQL++ mailing list, and I'll try to help you debug the problem.
You might also find the FOP and/or DocBook mailing lists helpful.




If you're looking to hack on the manual, here are some helpful resources
for getting up to speed on DocBook:

	Mills' "Installing And Using An XML/SGML DocBook Editing Suite" article:

		http://tinyurl.com/8alb2

		This is the best tutorial I've found.
		

	Walsh and Muellner's _Simplified DocBook: The Definitive Guide_ book:

		http://www.docbook.org/tdg/simple/en/html/sdocbook.html

		This is the most accessible reference.


	Walsh and Muellner's _DocBook: The Definitive Guide_ book, second
	edition, online version:

		http://www.docbook.org/tdg/en/html/docbook.html

		This is the official DocBook referece; the "Simplified" guide is a
		subset of this book.


	DocBook FAQ:

		http://www.dpawson.co.uk/docbook/

		Go here when you have a question that the tutorials and references
		do not answer.


	The official DocBook site:

		http://docbook.org/

Deleted doc/userman/common.xsl.
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





































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0" encoding="utf-8"?>

<!-- XSL stylesheet containing things common to both HTML and FO
     transformations. -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<!-- Autolabel sections, up to 2 levels deep.  Commented-out bit only
	     with recent DocBook stylesheets.
	<xsl:param name="section.autolabel.max.depth" select="2"/>
	-->
	<xsl:param name="section.autolabel" select="1"/>
	<xsl:param name="toc.section.depth" select="2"/>

	<!-- Hackery for 2-level deep autonumbering with old stylesheets,
	     from DocBook FAQ. -->
	<xsl:param name="section.label.includes.component.label" select="1"/>
	<xsl:param name="local.l10n.xml" select="document('')"/>
	<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
	  <l:l10n language="en">
			<l:context name="title-numbered">
				<l:template name="sect3" text="%t"/>
				<l:template name="sect4" text="%t"/>
				<l:template name="sect5" text="%t"/>
			</l:context>

			<l:context name="section-xref-numbered">
				<l:template name="sect3" 
				text="the section called &#8220;%t&#8221;"/>
				<l:template name="sect4" 
				text="the section called &#8220;%t&#8221;"/>
				<l:template name="sect5" 
				text="the section called &#8220;%t&#8221;"/>
			</l:context>
	  </l:l10n>
	</l:i18n>
</xsl:stylesheet>

Deleted doc/userman/fo.xsl.
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















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0" encoding="utf-8"?>

<!-- XSL stylesheet containing additions to the standard DocBook
     XSL-FO stylesheet.
-->

<xsl:stylesheet
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
		xmlns:fo="http://www.w3.org/1999/XSL/Format"
		version="1.0">
	
	<!-- Import the standard DocBook stylesheet that this one is based on.
	     We use a web URL, but the local XML catalog should resolve this to
			 the local copy of the stylesheet, if it exists. -->
	<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>

	<!-- Bring in local changes common to both HTML and FO output -->
	<xsl:include href="common.xsl"/>

	<!-- Add page breaks before each sect1, and define a processing
	     instruction that will let us add additional hard breaks when
			 needed.  From "DocBook XSL: The Complete Guide" 3/e -->
	<xsl:attribute-set name="section.level1.properties">
		<xsl:attribute name="break-before">page</xsl:attribute>
	</xsl:attribute-set>
	<xsl:template match="processing-instruction('hard-pagebreak')">
		<fo:block break-before='page'/>
	</xsl:template>

	<!-- Suppress ulinks from the DocBook from making hyperlinks in the
	  PDF, because most of them are relative links to the refman, and
	  these don't work correctly within a PDF.  If you want cross-links,
	  use the HTML manuals.  This code is from Bob Stayton, on the
	  docbook-apps mailing list. -->
	<xsl:template match="ulink" name="ulink">
		<xsl:choose>
			<xsl:when test="count(child::node())=0">
				<xsl:call-template name="hyphenate-url">
					<xsl:with-param name="url" select="@url"/>
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:apply-templates/>
			</xsl:otherwise>
		</xsl:choose> 
	</xsl:template>
</xsl:stylesheet>
Deleted doc/userman/html.xsl.
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































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0" encoding="utf-8"?>

<!-- XSL stylesheet containing additions to the standard DocBook
     chunked-HTML stylesheet.
-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
		version="1.0">
	
	<!-- Import the standard DocBook stylesheet that this one is based on.
	     We use a web URL, but the local XML catalog should resolve this to
			 the local copy of the stylesheet, if it exists. -->
	<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>

	<!-- Bring in local changes common to both HTML and FO output -->
	<xsl:include href="common.xsl"/>

	<!-- HTML-specific XSL parameters -->
	<xsl:param name="chunk.fast" select="0"/>
	<xsl:param name="html.stylesheet" select="'tangentsoft.css'"/>
	<xsl:param name="use.id.as.filename" select="1"/>

	<!-- Special ulink types, to reduce boilerplate link code -->
	<xsl:template match="ulink" name="refman_ulink">
		<xsl:choose>
			<!-- type=mysqlapi: makes hyperlinks to MySQL C API reference manual,
			     given only the function name with dashes instead of underscores
					 as the URL. -->
			<xsl:when test="@type = 'mysqlapi'">
				<tt>
					<a>
						<xsl:variable name="fn_dash" select="@url"/>
						<xsl:variable name="fn_name"
							select="translate($fn_dash, '-', '_')"/>
						<xsl:attribute name="href">
							<xsl:text>http://dev.mysql.com/doc/mysql/en/</xsl:text>
							<xsl:value-of select="$fn_dash"/>
							<xsl:text>.html</xsl:text>
						</xsl:attribute>
						<xsl:value-of select="$fn_name"/>
						<xsl:text>()</xsl:text>
					</a>
				</tt>
			</xsl:when>

			<!-- type=classref: makes hyperlinks to a class in the MySQL++
			     reference manual, given its name. -->
			<xsl:when test="@type = 'classref'">
				<tt>
					<a>
						<xsl:attribute name="href">
							<xsl:text>../refman/classmysqlpp_1_1</xsl:text>
							<xsl:value-of select="@url"/>
							<xsl:text>.html</xsl:text>
						</xsl:attribute>
						<xsl:choose>
							<xsl:when test="count(child::node())=0">
								<xsl:value-of select="@url"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:apply-templates/>
							</xsl:otherwise>
						</xsl:choose>
					</a>
				</tt>
			</xsl:when>

			<!-- type=structref: makes hyperlinks to a struct in the MySQL++
			     reference manual, given its name. -->
			<xsl:when test="@type = 'structref'">
				<tt>
					<a>
						<xsl:attribute name="href">
							<xsl:text>../refman/structmysqlpp_1_1</xsl:text>
							<xsl:value-of select="@url"/>
							<xsl:text>.html</xsl:text>
						</xsl:attribute>
						<xsl:choose>
							<xsl:when test="count(child::node())=0">
								<xsl:value-of select="@url"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:apply-templates/>
							</xsl:otherwise>
						</xsl:choose>
					</a>
				</tt>
			</xsl:when>

			<xsl:otherwise>
				<xsl:call-template name="ulink"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>
Deleted doc/userman/mktxt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19



















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/bin/sh
# Script to convert C++ source files to a text format, with 4 spaces for
# every tab, and with the leading block comment removed.  Used to
# reformat the example programs so they can be xincluded directly into
# the DocBook during XSLT processing.

TXTFILE=$1
SRCFILE=`echo ../../examples/$TXTFILE | sed -e s/\\\\.txt/.cpp/`
if [ ! -e $SRCFILE ]
then
	SRCFILE=`echo ../../examples/$TXTFILE | sed -e s/\\\\.txt/.h/`
fi
CLINE=`grep -n '\*\*/' $SRCFILE |cut -f1 -d:`
LINE=`echo $CLINE + 2 |bc`

#echo Converting $SRCFILE to $TXTFILE, starting at line $LINE...

expand -t4 $SRCFILE | tail -n +$LINE > $TXTFILE

Deleted doc/userman/userman.dbx.
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


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN"
        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<article>
<articleinfo>
    <title>MySQL++ User Manual</title>
    
    <authorgroup>
        <author>
            <firstname>Kevin</firstname>
            <surname>Atkinson</surname>
        </author>

        <author>
            <firstname>Sinisa</firstname>
            <surname>Milivojevic</surname>
        </author>

        <author>
            <firstname>Monty</firstname>
            <surname>Widenius</surname>
        </author>

        <author>
            <firstname>Warren</firstname>
            <surname>Young</surname>
        </author>
    </authorgroup>

    <copyright>
        <year>1998-2001, 2005-2007</year>
        <holder>Kevin Atkinson (original author)</holder>
        <holder>MySQL AB</holder>
        <holder>Educational Technology Resources</holder>
    </copyright>

    <pubdate role="rcs">$Date: 2007-06-28 00:17:10 -0600 (Thu, 28 Jun 2007) $</pubdate>
</articleinfo>


<sect1 id="intro">
    <title>Introduction</title>

    <para>MySQL++ is a powerful C++ wrapper for MySQL's C API.
    Its purpose is to make working with queries as easy as working
    with STL containers.</para>

    <para>The latest version of MySQL++ can be found at
    <ulink url="http://tangentsoft.net/mysql++/">the official web
    site</ulink>.</para>

    <para>Support for MySQL++ can be had on <ulink
    url="http://lists.mysql.com/plusplus">the mailing
    list</ulink>. That page hosts the mailing list archives, and
    tells you how you can subscribe.</para>


    <sect2>
        <title>A Brief History of MySQL++</title>

        <para>MySQL++ was created in 1998 by Kevin Atkinson. It
        started out MySQL-specific, but there were early efforts to
        try and make it database-independent, and call it SQL++. This
        is where the old library name "sqlplus" came from. This is
        also why the old versions prefixed some class names with
        "Mysql" but not others: the others were supposed to be the
        database-independent parts.</para>

        <para>Then in 1999, Sinisa Milivojevic unofficially
        took over maintenance of the library, releasing versions
        1.0 and 1.1. (All of Kevin's releases were pre-1.0 point
        releases.) Kevin gave over maintenance to Sinisa officially
        with 1.2, and ceased to have any involvement with the library's
        maintenance. Sinisa went on to maintain the library through
        1.7.9, released in mid-2001. Since Sinisa is an employee of
        <ulink url="http://www.mysql.com/">MySQL AB</ulink>, it seems
        to be during this time that the dream of multiple-database
        compatibility died.</para>

        <para>With version 1.7.9, MySQL++ went into a period of stasis,
        lasting over three years. During this time, Sinisa ran the
        MySQL++ mailing list and supported its users, but made no
        new releases. There were many patches submitted during this
        period, some of which were ignored, others which were just
        put on the MySQL++ web site for people to try. A lot of these
        patches were mutually-incompatible, and not all of them gave
        a fully-functional copy of MySQL++.</para>

        <para>In early August of 2004, the current maintainer (Warren
        Young) got fed up with this situation and took over. He
        released 1.7.10 later that month.</para>
    </sect2>


    <sect2>
        <title>If You Have Questions...</title>

        <para>If you want to email someone to ask questions about
        this library, we greatly prefer that you send mail to the
        <ulink url="http://lists.mysql.com/plusplus">MySQL++ mailing
        list</ulink>. The mailing list is archived, so if you have
        questions, do a search to see if the question has been asked
        before.</para>

        <para>You may find people's individual email addresses in
        various files within the MySQL++ distribution. Please do not
        send mail to them unless you are sending something that is
        inherently personal. Not all of the principal developers of
        MySQL++ are still active in its development; those who have
        dropped out have no wish to be bugged about MySQL++. Those of
        us still active in MySQL++ development monitor the mailing
        list, so you aren't getting any extra "coverage" by sending
        messages to additional email addresses.</para>
    </sect2>
</sect1>


<sect1 id="overview">
    <title>Overview</title>

    <para>MySQL++ has developed into a very complex and powerful
    library, with many different ways to accomplish the same
    task. Unfortunately, this means that figuring out how to perform
    a simple task can be frustrating for new users. In this section
    we will provide an overview of the most important user-facing
    components of the library.</para>

    <para>The overall process for using MySQL++ is similar to that
    of most other database access APIs:</para>

    <orderedlist>
        <listitem><para>Open the connection</para></listitem>
        <listitem><para>Form and execute the query</para></listitem>
        <listitem><para>Iterate through the result
        set</para></listitem> <listitem><para>Go to 2
        :)</para></listitem>
    </orderedlist>

    <para>There is, however, a lot of extra functionality along each
    step of the way.</para>


    <sect2>
        <title>The Connection Object</title>

        <para>A <ulink type="classref" url="Connection"/> object
        manages the connection to the MySQL server. You need at
        least one of these objects to do anything. Because the
        other MySQL++ objects your program will use often depend (at
        least indirectly) on the <classname>Connection</classname>
        instance, the <classname>Connection</classname> object needs
        to live at least as long as all other MySQL++ objects in
        your program.</para>
    </sect2>


    <sect2>
        <title>The Query Object</title>

        <para>Most often, you create SQL queries using a <ulink
        type="classref" url="Query"/> object created by the
        <classname>Connection</classname> object.</para>

        <para><classname>Query</classname> is subclassed
        from <classname>std::stringstream</classname>
        which means you can write to it like any other
        C++ stream to form a query. The library includes
        <ulink url="../../refman/html/manip_8h.html">stream
        manipulators</ulink> that make it easy to generate
        syntactically-correct SQL.</para>

        <para>You can also set up <xref linkend="tquery"/> with
        this class. Template queries work something like C's
        <function>printf()</function> function: you set up a fixed
        query string with tags inside that indicate where to insert
        the variable parts. If you have multiple queries that are
        structurally similar, you simply set up one template query,
        and use that in the various locations of your program.</para>

        <para>A third method for building queries is to use
        <classname>Query</classname> with <xref linkend="ssqls"/>
        (SSQLS). This feature presents your results as a C++ data
        structure, instead of making you access the data through
        MySQL++ intermediary classes. It also reduces the amount of
        embedded SQL code your program needs.</para>
    </sect2>


    <sect2>
        <title>Result Sets</title>

        <para>The field data in a result set are stored in a special
        <classname>std::string</classname>-like class called <ulink
        type="classref" url="ColData__Tmpl">ColData</ulink>.
        This class has conversion operators that let you
        automatically convert these objects to any of the basic C
        data types.  Additionally, MySQL++ defines classes like <ulink
        type="structref" url="DateTime"/>, which you can initialize
        from a MySQL <userinput>DATETIME</userinput> string. These
        automatic conversions are protected against bad conversions,
        and can either set a warning flag or throw an exception,
        depending on how you set the library up.</para>

        <para>As for the result sets as a whole, MySQL++ has a number
        of different ways of representing them:</para>

        <sect3>
            <title>Queries That Do Not Return Data</title>

            <para>Not all SQL queries return data. An example is
            <userinput>CREATE TABLE</userinput>. For these types
            of queries, there is a special result type (<ulink
            type="classref" url="ResNSel"/>) that simply reports the
            state resulting from the query: whether the query was
            successful, how many rows it impacted (if any), etc.</para>
        </sect3>

        <sect3>
            <title>Queries That Return Data: Dynamic Method</title>

            <para>The easiest way to retrieve data from MySQL
            uses a <ulink type="classref" url="Result"/> object,
            which includes one or more <ulink type="classref"
            url="Row"/> objects. Because these classes are
            <classname>std::vector</classname>-like containers, you
            can treat the result set as a two-dimensional array. For
            example, you can get the 5th item on the 2nd row by simply
            saying <methodname>result.at(1).at(4)</methodname>. You
            can also access row elements by field name, like this:
            <methodname>result.at(2)["price"]</methodname>.</para>

            <para>An alternate way of accessing your query results
            is through a <ulink type="classref" url="ResUse"/>
            object. This class acts more like an STL input iterator
            than a container: you walk through your result set one item
            at a time, always going forward. You can't seek around in
            the result set, and you can't know how many results are
            in the set until you find the end. This method is more
            efficient when there can be arbitrarily many results,
            which could pose a memory allocation problem with the
            previous technique.</para>
        </sect3>

        <sect3>
            <title>Queries That Return Data: Static Method</title>

            <para>The <xref linkend="ssqls"/> (SSQLS) feature
            method above defines C++ structures that match the table
            structures in your database schema.</para>

            <para>We call it the "static" method because the table
            structure is fixed at compile time. Indeed, some schema
            changes require that you update your SSQLS definitions
            and recompile, or else the program could crash or throw
            "bad conversion" exceptions when MySQL++ tries to stuff
            the new data into an outdated data structure.  (Not all
            changes require a recompile. Adding a column to a table
            is safe, for instance, as the program will ignore the
            new column until you update the SSQLS definition.)</para>

            <para>The advantage of this method is that your program
            will require very little embedded SQL code. You can
            simply execute a query, and receive your results as C++
            data structures, which can be accessed just as you would
            any other structure. The results can be accessed through
            the Row object, or you can ask the library to dump the
            results into a sequential or set-associative STL container
            for you. Consider this:</para>

            <programlisting>
vector&lt;mystruct&gt; v;
Query q = connection.query();
q &lt;&lt; "SELECT * FROM mytable";
q.storein(v);
for (vector&lt;mystruct&gt;::iterator it = v.begin(); it != v.end(); ++it) {
    cout &lt;&lt; "Price: " &lt;&lt; it-&gt;price &lt;&lt; endl;
}</programlisting>

            <para>Isn't that slick?</para>
        </sect3>
    </sect2>


    <sect2>
        <title>Exceptions</title>

        <para>By default, the library throws  <xref
        linkend="exceptions"/> whenever it encounters an error. You
        can ask the library to set an error flag instead, if you
        like, but the exceptions carry more information. Not only do
        they include a string member telling you why the exception
        was thrown, there are several exception types, so you can
        distinguish between different error types within a single
        <symbol>try</symbol> block.</para>
    </sect2>
</sect1>


<sect1 id="tutorial" xreflabel="Tutorial">
    <title>Tutorial</title>

    <para>This tutorial is meant to give you a jump start in using
    MySQL++. While it is a very complicated and powerful library,
    it's possible to make quite functional programs without tapping
    but a fraction of its power. This section will introduce you to
    the most useful fraction.</para>

    <para>This tutorial assumes you know C++ fairly well, in particular
    the Standard Template Library (STL) and exceptions.</para>


    <sect2>
        <title>Running the Examples</title>

        <para>All of the examples are complete running programs. If
        you built the library from source, the examples should
        have been built as well. If you installed it via the RPM
        package, the example source code and a simplified Makefile
        is in the examples subdirectory of the mysql++-devel
        package's documentation directory. (This is usually
        <filename>/usr/share/doc/mysql++-devel-*</filename>, but it
        can vary on different Linuxes.)</para>

        <para>Before you get started, please read through any of
        the README* files included with the MySQL++ distribution
        that are relevant to your platform. We won't repeat all of
        that here.</para>

        <para>Most of the examples require a test database, created
        by <filename>resetdb</filename>. You run it like so:</para>

        <screen>        ./exrun resetdb [host [user [password [port]]]]</screen>

        <para><filename>exrun</filename> is a shell script that
        ensures that the MySQL++ example program you give as its
        first argument finds the correct shared library version. If
        you run the example program directly, it will search the
        system directories for the MySQL++ shared library. That
        will only work correctly if you've installed the library
        before running the examples. You should run the examples
        before installing the library to ensure that the library
        is working correctly, thus <filename>exrun</filename>. See
        <filename>README.examples</filename> for more details. (We've
        been using POSIX file and path names for simplicity above, but
        there's a Windows version of <filename>exrun</filename>, called
        <filename>exrun.bat</filename>. It works the same way.)</para>

        <para>As for the remaining program arguments, they are all
        optional, but they must be in the order listed. If you leave
        off the port number, it uses the default value, 3306. If you
        leave off the password, it assumes you don't need one to
        log in.  If you leave off the user name, it uses the name
        you used when logging on to the computer. And if you leave
        off the host name, it assumes the MySQL server is running on
        the local host. A typical invocation is:</para>

        <screen>        ./exrun resetdb localhost root nunyabinness</screen>

        <para>For <filename>resetdb</filename>, the user name needs to
        be for an account with permission to create databases. Once
        the database is created, you can use any account that
        has read and write permissions for the sample database,
        <filename>mysql_cpp_data</filename>.</para>

        <para>You may also have to re-run <filename>resetdb</filename>
        after running some of the other examples, as they change
        the database.</para>
    </sect2>


    <sect2>
        <title>A Simple Example</title>

        <para>The following example demonstrates
        how to open a connection, execute a simple
        query, and display the results. This is
        <filename>examples/simple1.cpp</filename>:</para>

        <programlisting><xi:include href="simple1.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>This example simply gets the entire "item" column from
        the example table, and prints those values out.</para>

        <para>Notice that MySQL++'s <ulink type="classref"
        url="Result"/> objects work similarly to the STL
        <classname>std::vector</classname> container. The only trick
        is that you can't use subscripting notation if the argument
        is ever 0, because of the way we do overloading, so it's
        safer to call <function>at()</function> instead.</para>

        <para>The only thing that isn't explicit in the code above is
        that we delegate command line argument parsing and connection
        establishment to <function>connect_to_db()</function> in
        the <filename>util</filename> module. This function exists
        to give the examples a consistent interface, not to hide
        important details.</para>
    </sect2>


    <sect2>
        <title>A More Complicated Example</title>

        <para>The <filename>simple1</filename> example above
        was pretty trivial. Let's get a little deeper. Here is
        <filename>examples/simple2.cpp</filename>:</para>

        <programlisting><xi:include href="simple2.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>The main point of this example is that we're accessing
        fields in the row objects by name, instead of index. This is
        slower, but obviously clearer. We're also printing out the
        entire table, not just one column.</para>
    </sect2>


    <sect2 id="exceptions" xreflabel="exceptions">
        <title>Exceptions</title>

        <para>By default, MySQL++ uses exceptions to signal
        errors. Most of the examples have a full set of exception
        handlers. This is worthy of emulation.</para>

        <para>All of MySQL++'s custom exceptions derive
        from a common base class, <ulink type="classref"
        url="Exception"/>. That in turn derives from Standard C++'s
        <classname>std::exception</classname> class. Since the library
        can indirectly cause exceptions to come from the Standard C++
        Library, it's possible to catch all exceptions from MySQL++
        by just catching <classname>std::exception</classname> by
        reference. However, it's better to have individual catch blocks
        for each of the concrete exception types that you expect, and
        add a handler for either <classname>Exception</classname> or
        <classname>std::exception</classname> to act as a "catch-all"
        for unexpected exceptions.</para>

        <para>Some of these exceptions are optional. When exceptions
        are disabled on a MySQL++ object, it signals errors in some
        other way, typically by returning an error code or setting
        an error flag. Classes that support this feature derive
        from <ulink type="classref" url="OptionalExceptions"/>.
        Moreover, when such an object creates another object
        that also derives from this interface, it passes on its
        exception flag. Since everything flows from the <ulink
        type="classref" url="Connection"/> object, disabling
        exceptions on it at the start of the program disables all
        optional exceptions. You can see this technique at work in the
        <filename>simple[1-3]</filename> examples, which keeps them,
        well, simple.</para>

        <para>Real-world code typically can't afford to lose out on the
        additional information and control offered by exceptions. But
        at the same time, it is still sometimes useful to disable
        exceptions temporarily. To do this, put the section of
        code that you want to not throw exceptions inside a block,
        and create a <ulink type="classref" url="NoExceptions"/>
        object at the top of that block. When created, it saves the
        exception flag of the <classname>OptionalExceptions</classname>
        derivative you pass to it, and then disables exceptions
        on it. When the <classname>NoExceptions</classname>
        object goes out of scope at the end of the block,
        it restores the exceptions flag to its previous state.
        See <filename>examples/resetdb.cpp</filename> to see this
        technique at work.</para>

        <para>When one <classname>OptionalExceptions</classname>
        derivative passes its exceptions flag to another such object,
        it is only passing a copy. This means that the two objects'
        flags operate independently. There's no way to globally
        enable or disable this flag on existing objects in a single
        call. If you're using the <classname>NoExceptions</classname>
        feature and you're still seeing optional exceptions thrown, you
        disabled exceptions on the wrong object. The exception thrower
        could be unrelated to the object you disabled exceptions on,
        it could be its parent, or it could be a child created before
        you changed the exception throwing flag.</para>

        <para>Some of the exceptions MySQL++ can throw are not
        optional:</para>

        <itemizedlist>
            <listitem><para>The largest set of non-optional exceptions
            are those from the Standard C++ Library. For instance,
            if your code said "<varname>row[21]</varname>"
            on a row containing only 5 fields, the
            <classname>std::vector</classname> underlying the row
            object will throw an exception. (It will, that is,
            if it conforms to the standard.) You might consider
            wrapping your program's main loop in a try block catching
            <classname>std::exception</classname>s, just in case you
            trigger one of these exceptions.</para></listitem>

            <listitem><para><ulink type="classref"
            url="ColData__Tmpl">ColData</ulink> will always throw
            <ulink type="classref" url="BadConversion"/> when you
            ask it to do an improper type conversion. For example,
            you'll get an exception if you try to convert "1.25"
            to <type>int</type>, but not when you convert "1.00"
            to <type>int</type>. In the latter case, MySQL++
            knows that it can safely throw away the fractional
            part.</para></listitem>

            <listitem><para>If you use template queries and
            don't pass enough parameters when instantiating the
            template, <classname>Query</classname> will throw
            a <ulink type="classref" url="BadParamCount"/>
            exception.</para></listitem>

            <listitem><para>If you pass a bad option value to
            <methodname>Connection::set_option</methodname>, it will
            throw a <classname>BadOption</classname>
            exception.</para></listitem>
        </itemizedlist>

        <para>It's educational to modify the examples to force
        exceptions. For instance, misspell a field name, use
        an out-of-range index, or change a type to force a
        <classname>ColData</classname> conversion error.</para>
    </sect2>


    <sect2>
        <title>Quoting and Escaping</title>

        <para>SQL syntax often requires certain data to be
        quoted. Consider this query:</para>

        <programlisting>
SELECT * FROM stock WHERE item = 'Hotdog Buns' </programlisting>

        <para>Because the string "Hotdog Buns" contains a space,
        it must be quoted. With MySQL++, you don't have to add these
        quote marks manually:</para>

        <programlisting>
string s = "Hotdog Buns";
Query q = conn.query();
q &lt;&lt; "SELECT * FROM stock WHERE item = " &lt;&lt; quote_only &lt;&lt; s; </programlisting>

        <para>That code produces the same query string as in the
        previous example. We used the MySQL++ <type>quote_only</type>
        manipulator, which causes single quotes to be added
        around the next item inserted into the stream. This
        works for various string types, for any type of data
        that can be converted to MySQL++'s <ulink type="classref"
        url="ColData__Tmpl">ColData</ulink> type, and for <xref
        linkend="ssqls"/>. (The next section introduces the SSQLS
        feature.)</para>

        <para>Quoting is pretty simple, but SQL syntax also often
        requires that certain characters be "escaped". Imagine if the
        string in the previous example was "Frank's Brand Hotdog Buns"
        instead. The resulting query would be:</para>

        <programlisting>
SELECT * FROM stock WHERE item = 'Frank's Brand Hotdog Buns' </programlisting>

        <para>That's not valid SQL syntax. The correct syntax
        is:</para>

        <programlisting>
SELECT * FROM stock WHERE item = 'Frank''s Brand Hotdog Buns' </programlisting>

        <para>As you might expect, MySQL++ provides that feature,
        too, through its <type>escape</type> manipulator. But here,
        we want both quoting and escaping. That brings us to the most
        widely useful manipulator:</para>

        <programlisting>
string s = "Frank's Brand Hotdog Buns";
Query q = conn.query();
q &lt;&lt; "SELECT * FROM stock WHERE item = " &lt;&lt; quote &lt;&lt; s; </programlisting>

        <para>The <type>quote</type> manipulator both quotes strings,
        and escapes any characters that are special in SQL.</para>
    </sect2>


    <sect2>
        <title>Specialized SQL Structures</title>

        <sect3>
            <title>Retrieving data</title>

            <para>The next example introduces one of the most powerful
            features of MySQL++: <xref linkend="ssqls"/> (SSQLS). This
            is <filename>examples/custom1.cpp</filename>:</para>

            <programlisting><xi:include href="custom1.txt" parse="text" 
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>Here is the stock.h header used by that example,
            and many others:</para>

            <programlisting><xi:include href="stock.txt" parse="text"
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>As you can see, SSQLS is very powerful. It allows
            you to have a C++ structure paralleling your SQL table
            structure and use it easily with STL code.</para>
        </sect3>

        <sect3>
            <title>Adding data</title>

            <para>SSQLS can also be used to add data to a table. This
            is <filename>examples/custom2.cpp</filename>:</para>

            <programlisting><xi:include href="custom2.txt" parse="text" 
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>That's all there is to it!</para>

            <para>There is one subtlety: MySQL++ automatically quotes
            and escapes the data when building SQL queries using SSQLS
            structures. It's efficient, too: MySQL++ is smart enough
            to apply quoting and escaping only for those data types
            that actually require it.</para>

            <para>Because this example modifies the sample database,
            you may want to run resetdb after running this
            program.</para>
        </sect3>

        <sect3>
            <title>Modifying data</title>

            <para>It almost as easy to modify data with SSQLS. This
            is <filename>examples/custom3.cpp</filename>:</para>

            <programlisting><xi:include href="custom3.txt" parse="text"
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>When you run the example you will notice that in the
            WHERE clause only the 'item' field is checked for. This
            is because SSQLS also also less-than-comparable.</para>

            <para>Don't forget to run resetdb after running the
            example.</para>
        </sect3>

        <sect3>
            <title>Less-than-comparable</title>

            <para>SSQLS structures can be sorted and
            stored in STL associative containers as
            demonstrated in the next example. This is
            <filename>examples/custom4.cpp</filename>:</para>

            <programlisting><xi:include href="custom4.txt" parse="text"
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>For more details on the SSQLS feature, see the
            <xref linkend="ssqls"/> chapter.</para>
        </sect3>
    </sect2>


    <sect2>
        <title>C++ Equivalents of SQL Column Types</title>

        <para>In MySQL++ version 2.1, the new
        <filename>sql_types.h</filename> header declares typedefs
        for all MySQL column types. These typedefs all begin with
        <classname>sql_</classname> and end with a lowercase version of
        the standard SQL type name. For instance, the MySQL++ typedef
        corresponding to <classname>TINYINT UNSIGNED</classname>
        is <classname>mysqlpp::sql_tinyint_unsigned</classname>.
        You do not have to use these typedefs; you could use an
        <classname>unsigned char</classname> here if you wanted to. For
        that matter, you could use a plain <classname>int</classname>
        in most cases; MySQL++ is quite tolerant of this sort of
        thing. The typedefs exist for style reasons, for those who
        want their C++ code to use the closest equivalent type for
        any given SQL type.</para>

        <para>Most of these typedefs use standard C++ data types, but
        a few are aliases for a MySQL++ specific type. For instance,
        the SQL type <classname>DATETIME</classname> is mirrored in
        MySQL++ by <classname>mysqlpp::DateTime</classname>. For
        consistency, <filename>sql_types.h</filename> includes a
        typedef alias for <classname>DateTime</classname> called
        <classname>mysqlpp::sql_datetime</classname>.</para>
    </sect2>


    <sect2>
        <title>Handling SQL Nulls</title>

        <para>There is no equivalent of SQL's null in the standard C++
        type system.</para>

        <para>The primary distinction is one of type: in SQL, null
        is a column attribute, which affects whether that column
        can hold a SQL null. Just like the <symbol>const</symbol>
        keyword in the C++ type system, this effectively doubles the
        number of SQL data types. To emulate this, MySQL++ provides
        the <ulink type="classref" url="null">Null</ulink> template
        to allow the creation of distinct "nullable" versions of
        existing C++ types. So for example, if you have a <type>TINY
        INT UNSIGNED</type> column that can have nulls, the proper
        declaration for MySQL++ would be:</para>

        <programlisting>
mysqlpp::Null&lt;mysqlpp::sql_tinyint_unsigned&gt; myfield;</programlisting>

        <para>Template instantiations are first-class types in
        the C++ language, on par with any other type. You can
        use <classname>Null</classname> template instantiations
        anywhere you'd use the plain version of that type. (You can
        see a complete list of <classname>Null</classname> template
        instantiations for all column types that MySQL understands
        at the top of <filename>lib/type_info.cpp</filename>.)</para>

        <para>There's a secondary distinction between SQL null and
        anything available in the standard C++ type system: SQL null
        is a distinct value, equal to nothing else. We can't use
        C++'s <symbol>NULL</symbol> for this because it is ambiguous,
        being equal to 0 in integer context. MySQL++ provides the
        global <varname>null</varname> object, which you can assign
        to a <classname>Null</classname> template instance to make
        it equal to SQL null:</para>

        <programlisting>
myfield = mysqlpp::null;</programlisting>

        <para>The final aspect of MySQL++'s null handling is that,
        by default, it will enforce the uniqueness of the SQL null
        value. If you try to convert a SQL null to a plain C++
        data type, MySQL++ will throw a <ulink type="classref"
        url="BadNullConversion"/> exception. If you insert
        a SQL null into a C++ stream, you get "(NULL)". If
        you don't like this behavior, you can change it, by
        passing a different value for the second parameter to
        template <classname>Null</classname>. By default, this
        parameter is <ulink type="structref" url="NullisNull"/>,
        meaning that we should enforce the uniqueness of the null
        type. To relax this distinction, you can instantiate the
        <classname>Null</classname> template with a different
        behavior type: <ulink type="structref" url="NullisZero"/>
        or <ulink type="structref" url="NullisBlank"/>. Consider
        this code:</para>

        <programlisting>
mysqlpp::Null&lt;unsigned char, mysqlpp::NullisZero&gt; myfield;

myfield = mysqlpp::null;
cout &lt;&lt; myfield &lt;&lt; endl;

int x = myfield;
cout &lt;&lt; x &lt;&lt; endl;</programlisting>

        <para>This will print "0" twice. If you had used the
        default for the second <classname>Null</classname>
        template parameter, the first output statement would
        have printed "(NULL)", and the second would have thrown a
        <classname>BadNullConversion</classname> exception.</para>
    </sect2>


    <sect2>
        <title>Creating Transaction Sets</title>

        <para>MySQL++ v2.1 added the <ulink type="classref"
        url="Transaction"/> class, which makes it easier to use
        transactions in an exception-safe manner. Normally you create
        the <classname>Transaction</classname> object on the stack
        before you issue the queries in your transaction set. Then,
        when all the queries in the transaction set have been issued,
        you call <function>Transaction::commit()</function>,
        which commits the transaction set. If the
        <classname>Transaction</classname> object goes out of scope
        before you call <function>commit()</function>, the transaction
        set is rolled back. This ensures that if some code throws an
        exception after the transaction is started but before it is
        committed, the transaction isn't left unresolved.</para>

        <para><filename>examples/xaction.cpp</filename> illustrates
        this:</para>

        <programlisting><xi:include href="xaction.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
    </sect2>


    <sect2>
        <title>Which Query Type to Use?</title>

        <para>There are three major ways to execute a query in
        MySQL++: <methodname>Query::execute()</methodname>,
        <methodname>Query::store()</methodname>, and
        <methodname>Query::use()</methodname>. Which should you use,
        and why?</para>

        <para><methodname>execute()</methodname> is for queries
        that do not return data <emphasis>per se</emphasis>. For
        instance, <userinput>CREATE INDEX</userinput>. You do
        get back some information from the MySQL server, which
        <methodname>execute()</methodname> returns to its caller in a
        <ulink type="classref" url="ResNSel"/> object. In addition to
        the obvious &mdash; a flag stating whether the query succeeded
        or not &mdash; this object also contains things like the
        number of rows that the query affected. If you only need the
        success status, there's <methodname>Query::exec()</methodname>,
        which just returns bool.</para>

        <para>If your query does pull data from the database,
        the simplest option is <methodname>store()</methodname>.
        This returns a <ulink type="classref" url="Result"/> object,
        which contains an in-memory copy of the result set. The nice
        thing about this is that <classname>Result</classname> is a
        sequential container, like <classname>std::vector</classname>,
        so you can iterate through it forwards and backwards, access
        elements with subscript notation, etc. There are also the
        <methodname>storein()</methodname> methods, which actually
        put the result set into an STL container of your choice. The
        downside of these methods is that a sufficiently large result
        set will give your program memory problems.</para>

        <para>For these large result sets, the superior option is a
        <methodname>use()</methodname> query. This returns a <ulink
        type="classref" url="ResUse"/> object, which is similar to
        Result, but without all of the random-access features. This
        is because a "use" query tells the database server to
        send the results back one row at a time, to be processed
        linearly. It's analogous to a C++ stream's input iterator,
        as opposed to a random-access iterator that a container like
        vector offers. By accepting this limitation, you can process
        arbitrarily large result sets. This technique is demonstrated
        in <filename>examples/simple3.cpp</filename>:</para>

        <programlisting><xi:include href="simple3.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>This example does the same thing as
        <filename>simple2</filename>, only with a "use" query instead
        of a "store" query. If your program uses exceptions, you should
        instead look at <filename>examples/usequery.cpp</filename>,
        which does the same thing as <filename>simple3</filename>,
        but with exception-awareness.</para>
    </sect2>


    <sect2>
        <title>Conditional Result Row Handling</title>

        <para><methodname>Query::store()</methodname> is fine if
        you really need all the rows the query returns. It sometimes
        happens that you can't express the full selection criteria
        in a SQL query. Instead of storing the full result set,
        then picking over it to find the rows you want to keep,
        use <methodname>Query::store_if()</methodname>.  This is
        <filename>examples/store_if.cpp</filename>:</para>

        <programlisting><xi:include href="store_if.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>I doubt anyone really needs to select rows from
        a table that have a prime number in a given field. This
        example is meant to be just barely more complex than SQL
        can manage, to avoid obscuring the point. Point being, the
        <methodname>Query::store_if()</methodname> call here gives
        you a container full of results meeting a criterion that you
        probably can't express in SQL. You will no doubt have much
        more useful criteria in your own programs.</para>

        <para>If you need a more complex query than the one
        <methodname>store_if()</methodname> knows how to build when
        given an SSQLS examplar, there are two overloads that let
        you use your own query string. One overload takes the query
        string directly, and the other uses the query string built
        with <classname>Query</classname>'s stream interface.</para>
    </sect2>


    <sect2>
        <title>Executing Code for Each Row In a Result Set</title>

        <para>SQL is more than just a database query language. Modern
        database engines can actually do some calculations on the data
        on the server side. But, this isn't always the best way to
        get something done. When you need to mix code and a query,
        MySQL++'s new <methodname>Query::for_each()</methodname>
        facility might be just what you need. This is
        <filename>examples/for_each.cpp</filename>:</para>

        <programlisting><xi:include href="for_each.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>You only need to read the <function>main()</function>
        function to get a good idea of what the program
        does. The key line of code passes an SSQLS examplar and
        a functor to <methodname>Query::for_each()</methodname>.
        <methodname>for_each()</methodname> uses the SSQLS instance to
        build a <computeroutput>select * from TABLE</computeroutput>
        query, <computeroutput>stock</computeroutput> in
        this case. It runs that query internally, calling
        <classname>gather_stock_stats</classname> on each row. This
        is a pretty contrived example; you could actually do this in
        SQL, but we're trying to prevent the complexity of the code
        from getting in the way of the demonstration here.</para>

        <para>Just as with <methodname>store_if()</methodname>,
        described above, there are two other overloads for
        <methodname>for_each()</methodname> that let you use your
        own query string.</para>
    </sect2>


    <sect2>
        <title>Getting Field Meta-Information</title>

        <para>The following example demonstrates how to get
        information about the fields in a result set, such
        as the name of the field and the SQL type. This is
        <filename>examples/fieldinf1.cpp</filename>:</para>

        <programlisting><xi:include href="fieldinf1.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
    </sect2>


    <sect2>
        <title>Dealing with Binary Data</title>

        <para>The tricky part about dealing with binary data in
        MySQL++ is to ensure that you don't ever treat the data as a
        C string, which is really easy to do accidentally. C strings
        treat zero bytes as special end-of-string characters, but
        they're not special at all in binary data. Recent releases
        of MySQL++ do a better job of letting you keep data in
        forms that don't have this problem, but it's still possible
        to do it incorrectly. These examples demonstrate correct
        techniques.</para>

        <sect3>
            <title>Loading a binary file into a BLOB column</title>

            <para>This example shows how to insert binary data
            into a MySQL table's BLOB column with MySQL++,
            and also how to get the value of the auto-increment
            column from the previous insert. (This MySQL feature
            is usually used to create unique IDs for rows as
            they're inserted.) The program requires one command
            line parameter over that required by the other examples
            you've seen so far, the path to a JPEG file. This is
            <filename>examples/load_jpeg.cpp</filename>:</para>

            <programlisting><xi:include href="load_jpeg.txt" parse="text"
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>Notice that we used the <type>escape</type>
            manipulator when building the INSERT query above. This
            is because we're not using one of the MySQL++ types that
            does automatic escaping and quoting.</para>
        </sect3>

        <sect3>
            <title>Serving images from BLOB column via CGI</title>

            <para>This example is also a very short one, considering
            the function that it performs. It retreives data loaded
            by <filename>load_jpeg</filename> and prints it out in
            the form a web server can accept for a CGI call. This
            is <filename>examples/cgi_jpeg.cpp</filename>:</para>

            <programlisting><xi:include href="cgi_jpeg.txt" parse="text"
            xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

            <para>You install this in a web server's
            CGI program directory (usually called
            <filename>cgi-bin</filename>), then call it with a URL like
            <userinput>http://my.server.com/cgi-bin/cgi_jpeg?id=1</userinput>.
            That retrieves the JPEG with ID 1 from the table and
            returns it to the web server, which will send it on to
            the browser.</para>
        </sect3>
    </sect2>
</sect1>


<sect1 id="tquery" xreflabel="Template Queries">
    <title>Template Queries</title>

    <para>Another powerful feature of MySQL++ is being able
    to set up template queries. These are kind of like C's
    <function>printf()</function> facility: you give MySQL++ a string
    containing the fixed parts of the query and placeholders for
    the variable parts, and you can later substitute in values into
    those placeholders.</para>

    <para>The following program demonstrates how to use this
    feature. This is <filename>examples/tquery.cpp</filename>:</para>

    <programlisting><xi:include href="tquery.txt" parse="text" 
    xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

    <para>The line just before the call to
    <methodname>query.parse()</methodname> sets the template, and the
    parse call puts it into effect. From that point on, you can re-use
    this query by calling any of several Query member functions that
    accept query template parameters. In this example, we're using
    <methodname>Query::execute()</methodname>.</para>

    <para>Let's dig into this feature a little deeper.</para>


    <sect2>
        <title>Setting up Template Queries</title>

        <para>To set up a template query, you simply insert it into the
        Query object, using numbered placeholders wherever you want
        to be able to change the query. Then, you call the parse()
        function to tell the Query object that the query string is
        a template query, and it needs to parse it:</para>

        <programlisting>
query &lt;&lt; "select (%2:field1, %3:field2) from stock where %1:wheref = %0q:what";
query.parse();</programlisting>

        <para>The format of the placeholder is:</para>

        <programlisting>
%###(modifier)(:name)(:)</programlisting>

        <para>Where '###' is a number up to three digits. It is
        the order of parameters given to a <ulink type="classref"
        url="SQLQueryParms"/> object, starting from 0.</para>

        <para>'modifier' can be any one of the following:</para>

        <blockquote>
        <informaltable frame="none">
        <tgroup cols="2">
        <colspec colsep="1" rowsep="1"/>
        <tbody>
            <row>
                <entry><emphasis role="bold">%</emphasis></entry>
                <entry>Print an actual "%"</entry>
            </row>
            <row>
                <entry><emphasis role="bold">""</emphasis></entry>
                <entry>Don't quote or escape no matter what.</entry>
            </row>
            <row>
                <entry><emphasis role="bold">q</emphasis></entry>
                <entry>This will quote and escape
                the item using the MySQL C API
                function <ulink url="mysql-escape-string"
                type="mysqlapi"/> if it is a string or char *,
                or another MySQL-specific type
                that needs to be quoted.</entry>
            </row>
            <row>
                <entry><emphasis role="bold">Q</emphasis></entry>
                <entry>Quote but don't escape
                based on the same rules as for 'q'. This
                can save a bit of processing time if you
                know the strings will never need
                quoting</entry>
            </row>
            <row>
                <entry><emphasis role="bold">r</emphasis></entry>
                <entry>Always quote and escape
                even if it is a number.</entry>
            </row>
            <row>
                <entry><emphasis role="bold">R</emphasis></entry>
                <entry>Always quote but
                don't escape even if it is
                a number.</entry>
            </row>
        </tbody>
        </tgroup>
        </informaltable>
        </blockquote>

        <para>":name" is for an optional name which aids in filling
        SQLQueryParms. Name can contain any alpha-numeric characters
        or the underscore. You can have a trailing colon, which will
        be ignored. If you need to represent an actual colon after
        the name, follow the name with two colons. The first one will
        end the name and the second one won't be processed.</para>
    </sect2>


    <sect2>
        <title>Setting the Parameters at Execution Time</title>

        <para>To specify the parameters when you want to execute
        a query simply use <methodname>Query::store(const
        SQLString &amp;parm0, [..., const SQLString
        &amp;parm11])</methodname>. This type of multiple overload
        also exists for <methodname>Query::storein()</methodname>,
        <methodname>Query::use()</methodname> and
        <methodname>Query::execute()</methodname>. 'parm0'
        corresponds to the first parameter, etc. You may specify up
        to 25 parameters. For example:</para>

        <programlisting>
Result res = query.store("Dinner Rolls", "item", "item", "price")</programlisting>

        <para>with the template query provided above would
        produce:</para>

        <programlisting>
select (item, price) from stock where item = "Dinner Rolls"</programlisting>

        <para>The reason we didn't put the template parameters in
        numeric order...</para>

        <programlisting>
select (%0:field1, %1:field2) from stock where %2:wheref = %3q:what</programlisting>

        <para>...will become apparent shortly.</para>
    </sect2>


    <sect2>
        <title>Parameter Types and Function Overloads</title>

        <para>There are quite a few overloads for each of
        <classname>Query</classname>'s query execution
        functions. (<methodname>store()</methodname>,
        <methodname>use()</methodname>,
        <methodname>execute()</methodname>...) It's possible to
        have code that looks like it should work, but which doesn't,
        because it's calling the wrong overload. For instance:</para>

        <programlisting>
query.storein(my_vector, "1");
query.storein(my_vector, 1);</programlisting>

        <para>The first one works, and the second does
        not. The cause is a vestigial second parameter to one
        of <methodname>storein()</methodname>'s overloads that's
        compatible with integers. Being vestigial, it's only getting
        in the way right now, but we can't fix it until the next
        major version of the libary, where it will be okay to break
        the ABI. Until then, we're stuck with it.</para>

        <para>If the MySQL server keeps rejecting your template
        queries, try explicitly casting the parameters to
        <classname>SQLString</classname>:</para>

        <programlisting>
query.storein(my_vector, SQLString(1));</programlisting>

        <para>This ensures that your code calls one of the overloads
        meant to handle template query parameters. I don't recommend
        doing this habitually, because it will clutter your code. For
        the most part, MySQL++'s interface is set up to do the right
        thing. It's just that there are still a few corner cases
        that can't be fixed until the next time we can redesign the
        interface.</para>
    </sect2>

    <sect2>
        <title>Default Parameters</title>

        <para>The template query mechanism allows you to set
        default parameter values. You simply assign a value
        for the parameter to the appropriate position in the
        <varname>Query::def</varname> array. You can refer to the
        parameters either by position or by name:</para>

        <programlisting>
query.def[1] = "item";
query.def["wheref"] = "item";</programlisting>

        <para>Both do the same thing.</para>

        <para>This mechanism works much like C++'s default function
        parameter mechanism: if you set defaults for the parameters at
        the end of the list, you can call one of
        <classname>Query</classname>'s query execution methods without
        passing all of the values. If the query takes four parameters
        and you've set defaults for the last three, you can execute the
        query using as little as just one explicit parameter.</para>

        <para>Now you can see why we numbered the template query
        parameters the way we did a few sections earlier. We ordered
        them so that the ones less likely to change have higher
        numbers, so we don't always have to pass them. We can just give
        them defaults and take those defaults when applicable. This
        is most useful when some parameters in a template query vary
        less often than other parameters. For example:</para>

        <programlisting>
query.def["field1"] = "item"; 
query.def["field2"] = "price"; 
Result res1 = query.store("Hamburger Buns", "item"); 
Result res2 = query.store(1.25, "price"); </programlisting>

        <para>This stores the result of the following queries
        in <varname>res1</varname> and <varname>res2</varname>,
        respectively:</para>

        <programlisting>
select (item, price) from stock where item = "Hamburger Buns"
select (item, price) from stock where price = 1.25</programlisting>

        <para>Default parameters are useful in this example because
        we have two queries to issue, and parameters 2 and 3 remain
        the same for both, while parameters 0 and 1 vary.</para>

        <para>Some have been tempted into using this mechanism as a
        way to set all of the template parameters in a query:</para>

        <programlisting>
query.def["what"] = "Hamburger Buns";
query.def["wheref"] = "item";
query.def["field1"] = "item"; 
query.def["field2"] = "price"; 
Result res1 = query.store();</programlisting>

        <para>This can work, but it is <emphasis>not designed
        to</emphasis>. In fact, it's known to fail horribly in one
        common case. You will not get sympathy if you complain on
        the mailing list about it not working. If your code doesn't
        actively reuse at least one of the parameters in subsequent
        queries, you're abusing MySQL++, and it is likely to take
        its revenge on you.</para>
    </sect2>


    <sect2>
        <title>Error Handling</title>

        <para>If for some reason you did not specify all the parameters
        when executing the query and the remaining parameters do not
        have their values set via <varname>Query::def</varname>,
        the query object will throw a <ulink type="classref"
        url="BadParamCount"/> object. If this happens, you
        can get an explanation of what happened by calling
        <methodname>BadParamCount::what()</methodname>, like so:</para>

        <programlisting>
query.def["field1"] = "item"; 
query.def["field2"] = "price"; 
Result res = query.store(1.25); </programlisting>

        <para>This would throw <classname>BadParamCount</classname>
        because the <varname>wheref</varname> is not specified.</para>

        <para>In theory, this exception should never be thrown. If
        the exception is thrown it probably a logic error in your
        program.</para>
    </sect2>
</sect1>


<sect1 id="ssqls" xreflabel="Specialized SQL Structures">
    <title>Specialized SQL Structures</title>

    <para>The Specialized SQL Structure (SSQLS) feature lets you
    easily define C++ structures that match the form of your SQL
    tables. Because of the extra functionality that this feature builds
    into these structures, MySQL++ can populate them automatically
    when retrieving data from the database; with queries returning
    many records, you can ask MySQL++ to populate an STL container of
    your SSQLS records with the results. When updating the database,
    MySQL++ can use SSQLS structures to match existing data, and it
    can insert SSQLS structures directly into the database.</para>

    <para>You define an SSQLS using one of several macros. (These
    are in the file custom.h, and in the file that it includes,
    custom-macros.h.) There are a bunch of different macros, for
    different purposes. The following sections will discuss each macro
    type separately, beginning with the easiest and most generally
    useful.</para>


    <sect2>
        <title>sql_create</title>

        <para>This is the most basic sort of SSQLS declaration:</para>

        <programlisting>
sql_create_5(stock, 1, 0,
    string, item,
    int, num,                  
    double, weight,  
    double, price,  
    mysqlpp::Date, date)</programlisting>

        <para>This creates a C++ structure called
        <classname>stock</classname> containing five member
        variables (<varname>item</varname>, <varname>num</varname>,
        <varname>weight</varname>, <varname>price</varname> and
        <varname>date</varname>), along with some constructors and
        other member functions useful with MySQL++.</para>

        <para>One of the generated constructors takes a reference
        to a mysqlpp::Row object, allowing you to easily populate a
        vector of stocks like so:</para>

        <programlisting>
vector&lt;stock&gt; result; 
query.storein(result);</programlisting>

        <para>That's all there is to it. The only requirements are
        that the table structure be compatible with the SSQLS's member
        variables, and that the fields are in the same order.</para>

        <para>The general format of this set of macros is:</para>

        <programlisting>
sql_create_#(NAME, COMPCOUNT, SETCOUNT, TYPE1, ITEM1, ... TYPE#, ITEM#)</programlisting>

        <para>Where # is the number of member variables,
        <parameter>NAME</parameter> is the name of the structure you
        wish to create, <parameter>TYPEx</parameter> is the type of
        a member variable, and <parameter>ITEMx</parameter> is that
        variable's name.</para>

        <para>The <parameter>COMPCOUNT</parameter> and
        <parameter>SETCOUNT</parameter> arguments are described in
        the next section.</para>
    </sect2>


    <sect2>
        <title>SSQLS Comparison and Initialization</title>

        <para><varname>sql_create_</varname><emphasis>x</emphasis>
        adds member functions and operators to each SSQLS that
        allow you to compare one SSQLS instance to another. These
        functions compare the first <parameter>COMPCOUNT</parameter>
        fields in the structure. In the example above,
        <parameter>COMPCOUNT</parameter> is 1, so only the
        <varname>item</varname> field will be checked when comparing
        two <classname>stock</classname> structures.</para>

        <para>This feature works best when your table's "key"
        fields are the first ones in the table schema and you set
        <parameter>COMPCOUNT</parameter> equal to the number of key
        fields.  That way, a check for equality between two SSQLS
        structures in your C++ code will give the same results as a
        check for equality in SQL.</para>

        <para><parameter>COMPCOUNT</parameter> must
        be at least 1. The current implementation of
        <varname>sql_create_</varname><emphasis>x</emphasis> cannot
        create an SSQLS without comparison member functions.</para>

        <para>Because our <classname>stock</classname> structure
        is less-than-comparable, you can use it in STL algorithms
        and containers that require this, such as STL's associative
        containers:</para>

        <programlisting>
std::set&lt;stock&gt; result;   
query.storein(result);
cout &lt;&lt; result.lower_bound(stock("Hamburger"))-&gt;item &lt;&lt; endl;</programlisting>

        <para>This will print the first item in the result set that
        begins with "Hamburger".</para>

        <para>The third parameter to
        <varname>sql_create_</varname><emphasis>x</emphasis> is
        <parameter>SETCOUNT</parameter>. If this is nonzero, it adds an
        initialization constructor and a <function>set()</function>
        member function taking the given number of arguments,
        for setting the first <emphasis>N</emphasis> fields of the
        structure. For example, you could change the above example
        like so:</para>

        <programlisting>
sql_create_5(stock, 1, 2,
    string, item,
    int, num,                  
    double, weight,  
    double, price,  
    mysqlpp::Date, date)
        
stock foo("Hotdog", 52);</programlisting>

        <para>In addition to this 2-parameter constructor, this version
        of the <classname>stock</classname> SSQLS will have a similar
        2-parameter <function>set()</function> member function.</para>

        <para>The <parameter>COMPCOUNT</parameter> and
        <parameter>SETCOUNT</parameter> values cannot be equal. If
        they are, the macro will generate two initialization
        constructors with identical parameter lists, which
        is illegal in C++. Why does this happen? It's often
        convenient to be able to say something like <userinput>x
        == stock("Hotdog")</userinput>. This requires that there
        be a constructor taking <parameter>COMPCOUNT</parameter>
        arguments to create the temporary <classname>stock</classname>
        instance used in the comparison. It is easy to work around
        this limitation. Using our <classname>stock</classname>
        example structure, if you wanted comparisons to consider all
        5 fields and also be able to initialize all 5 fields at once,
        you would pass 5 for <parameter>COMPCOUNT</parameter> and
        0 for <parameter>SETCOUNT</parameter>. You would still get
        a 5-parameter initialization constructor and a 5-parameter
        <function>set()</function> function.</para>
    </sect2>


    <sect2>
        <title>Retrieving a Table Subset</title>

        <para>It's not necessary to retrieve an entire table
        row using SSQLS, as long as the fields you want are
        grouped together at the start of the table schema.
        <filename>examples/custom6.cpp</filename> illustrates
        this:</para>

        <programlisting><xi:include href="custom6.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>(See the simple1 example in the <xref
        linkend="tutorial"/> for another way to accomplish the same
        thing.)</para>

        <para>This example illustrates an important point: you
        could not use the 5-member <classname>stock</classname>
        structure in this example. The reason is, when you assign a
        <classname>Row</classname> object to an SSQLS, the function
        that copies the row's data into the structure expects to
        see as many fields in the row as are in the SSQLS. Your
        program will crash when the code tries to access fields
        beyond those that exist in the <classname>Row</classname>
        object. The converse is not true, however: if you change
        the <userinput>SELECT</userinput> statement above so that
        it retrieves more than one column, the code will still
        work, because the extra fields in each row will simply be
        ignored.</para>

        <para>Realize that the second and third parameters to
        <varname>sql_create_1</varname> can't be anything other
        than 1 and 0, respectively. As discussed above, the second
        parameter must be at least 1, but since there is only one
        field in the structure, it cannot be higher than 1. Since
        the third parameter cannot be equal to the second, only 0
        works there.</para>
    </sect2>


    <sect2>
        <title>Additional Features of Specialized SQL
        Structures</title>

        <para>Up to this point, we haven't been using all of the
        features in the SSQLS structures we've been generating. We
        could have used the <symbol>sql_create_basic_*</symbol>
        macros instead, which would have worked just as well for
        what we've seen so far, and the generated code would have
        been smaller.</para>

        <para>Why is it worth ignoring the "basic" variants of these
        macros, then? Consider this:</para>

        <programlisting>
query.insert(s);</programlisting>

        <para>This does exactly what you think it does: it inserts
        's' into the database. This is possible because a standard
        SSQLS has functions that the query object can call to get
        the list of fields and such, which it uses to build an
        insert query.  <methodname>query::update()</methodname> and
        <methodname>query::replace()</methodname> also rely on this
        SSQLS feature. A basic SSQLS lacks these functions.</para>

        <para>Another feature of standard SSQLSes you might find a use
        for is changing the table name used in queries. By default,
        the table in the MySQL database is assumed to have the same
        name as the SSQLS structure type. But if this is inconvenient,
        you can globally change the table name used in queries like
        this:</para>

        <programlisting>
stock::table() = "MyStockData";</programlisting>
    </sect2>


    <sect2>
        <title>Harnessing SSQLS Internals</title>

        <para>Continuing the discussion in the previous section,
        there is a further set of methods that the non-"basic"
        versions of the <symbol>sql_create</symbol> macros define
        for each SSQLS. These methods are mostly for use within the
        library, but some of them are useful enough that you might
        want to harness them for your own ends. Here is some pseudocode
        showing how the most useful of these methods would be defined
        for the <structname>stock</structname> structure used in all
        the <filename>custom*.cpp</filename> examples:</para>

        <programlisting>
// Basic form
template &lt;class Manip&gt;   
stock_value_list&lt;Manip&gt; value_list(cchar *d = &#34;,&#34;,
    Manip m = mysqlpp::quote) const;  

template &lt;class Manip&gt;   
stock_field_list&lt;Manip&gt; field_list(cchar *d = &#34;,&#34;,   
    Manip m = mysqlpp::do_nothing) const;  

template &lt;class Manip&gt;   
stock_equal_list&lt;Manip&gt; equal_list(cchar *d = &#34;,&#34;,
    cchar *e = &#34; = &#34;, Manip m = mysqlpp::quote) const;  


// Boolean argument form
template &lt;class Manip&gt;
stock_cus_value_list&lt;Manip&gt; value_list([cchar *d, [Manip m,] ]   
    bool i1, bool i2 = false, ... , bool i5 = false) const;  

// List form  
template &lt;class Manip&gt;
stock_cus_value_list&lt;Manip&gt; value_list([cchar *d, [Manip m,] ]  
    stock_enum i1, stock_enum i2 = stock_NULL, ...,
    stock_enum i5 = stock_NULL) const;  

// Vector form  
template &lt;class Manip&gt;
stock_cus_value_list&lt;Manip&gt; value_list([cchar *d, [Manip m,] ]  
    vector&lt;bool&gt; *i) const;  

...Plus the obvious equivalents for field_list() and equal_list()</programlisting>

        <para>Rather than try to learn what all of these methods do at
        once, let's ease into the subject. Consider this code:</para>

        <programlisting>
stock s("Dinner Rolls", 75, 0.95, 0.97, "1998-05-25");   
cout &lt;&lt; "Value list: " &lt;&lt; s.value_list() &lt;&lt; endl;  
cout &lt;&lt; "Field list: " &lt;&lt; s.field_list() &lt;&lt; endl;  
cout &lt;&lt; "Equal list: " &lt;&lt; s.equal_list() &lt;&lt; endl;</programlisting>

        <para>That would produce something like:</para>

        <programlisting>
Value list: 'Dinner Rolls',75,0.95,0.97,'1998-05-25'   
Field list: item,num,weight,price,date  
Equal list: item = 'Dinner Rolls',num = 75,weight = 0.95, price = 0.97,date = '1998-05-25'</programlisting>

        <para>That is, a "value list" is a list of data member values
        within a particular SSQLS instance, a "field list" is a list
        of the fields (columns) within that SSQLS, and an "equal list"
        is a list in the form of an SQL equals clause.</para>

        <para>Just knowing that much, it shouldn't surprise you
        to learn that <methodname>Query::insert()</methodname> is
        implemented more or less like this:</para>

        <programlisting>
*this &lt;&lt; "INSERT INTO " &lt;&lt; v.table() &lt;&lt; " (" &lt;&lt; v.field_list() &lt;&lt;
        ") VALUES (" &lt;&lt; v.value_list() &lt;&lt; ")";</programlisting>

        <para>where 'v' is the SSQLS you're asking the Query object
        to insert into the database.</para>

        <para>Now let's look at a complete example,
        which uses one of the more complicated forms of
        <methodname>equal_list()</methodname>. This example
        builds a query with fewer hard-coded strings than
        the most obvious technique requires, which makes
        it more robust in the face of change. Here is
        <filename>examples/custom5.cpp</filename>:</para>

        <programlisting><xi:include href="custom5.txt" parse="text" 
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>

        <para>This example uses the list form of
        <methodname>equal_list()</methodname>. The
        arguments <varname>stock_weight</varname>
        and <varname>stock_price</varname> are enum
        values equal to the position of these columns
        within the <structname>stock</structname> table.
        <symbol>sql_create_</symbol><emphasis>x</emphasis> generates
        this enum for you automatically.</para>

        <para>The boolean argument form of that
        <methodname>equal_list()</methodname> call would look like
        this:</para>

        <programlisting>
query &lt;&lt; "select * from stock where " &lt;&lt;
        res[0].equal_list(" and ", false, false, true, true, false);</programlisting>

        <para>It's a little more verbose, as you can see. And if you
        want to get really complicated, use the vector form:</para>

        <programlisting>
vector&lt;bool&gt; v(5, false);
v[stock_weight] = true;
v[stock_price] = true;
query &lt;&lt; "select * from stock where " &lt;&lt;
        res[0].equal_list(" and ", v);</programlisting>

        <para>This form makes the most sense if you are building many
        other queries, and so can re-use that vector object.</para>

        <para>Many of these methods accept manipulators and custom
        delimiters. The defaults are suitable for building SQL queries,
        but if you're using these methods in a different context,
        you may need to override these defaults. For instance, you
        could use these methods to dump data to a text file using
        different delimiters and quoting rules than SQL.</para>

        <para>At this point, we've seen all the major aspects of the
        SSQLS feature. The final sections of this chapter look at
        some of the peripheral aspects.</para>
    </sect2>


    <sect2>
        <title>Alternate Creation Methods</title>

        <para>If for some reason you want your SSQLS data members
        to have different names than used in the MySQL database,
        you can do so like this:</para>

        <programlisting>
sql_create_c_names_5(stock, 1, 5,        
    string, item, "item",
    int, num, "quantity",  
    double, weight, "weight",  
    double, price, "price"  
    mysqlpp::Date, date, "shipment")</programlisting>

        <para>If you want your SSQLS to have its data members in a
        different order from those in the MySQL table, you can do it
        like this:</para>

        <programlisting>
sql_create_c_order_5(stock, 2, 5,   
    mysqlpp::Date, date, 5,
    double, price, 4,   
    string, item, 1,    
    int, num, 2,   
    double, weight, 3)</programlisting>

        <para>You can combine the custom names and custom ordering
        like this:</para>

        <programlisting>
sql_create_complete_5(stock, 2, 5,   
    mysqlpp::date, date, "shipment", 5,
    double, price, "price", 4,
    string, item, "item", 1,
    int, num, "quantity", 2,
    double, weight, "weight", 3)</programlisting>

        <para>All three of these macro types have "basic" variants
        that work the same way. Again, basic SSQLSes lack the features
        necessary for automatic insert, update and replace query
        creation.</para>
    </sect2>


    <sect2>
        <title>Expanding SSQLS Macros</title>

        <para>If you ever need to see the code that a given
        SSQLS declaration expands out to, use the utility
        <filename>doc/ssqls-pretty</filename>, like so:</para>

        <programlisting>
doc/ssqls-pretty &lt; myprog.cpp |less</programlisting>

        <para>This Perl script locates the first SSQLS declaration
        in that file, then uses the C++ preprocessor to expand that
        macro. (The script assumes that your system's preprocessor
        is called <filename>cpp</filename>, and that its command line
        interface follows Unix conventions.)</para>

        <para>If you run it from the top MySQL++ directory, as shown
        above, it will use the header files in the distribution's
        <filename>lib</filename> subdirectory. Otherwise, it
        assumes the MySQL++ headers are in their default location,
        <filename>/usr/include/mysql++</filename>. If you want to
        use headers in some other location, you'll need to change
        the directory name in <command>-I</command> flag at the top
        of the script.</para>
    </sect2>


    <sect2>
        <title>Extending the SSQLS Mechanism</title>

        <para>The SSQLS headers &mdash; custom.h and custom-macros.h
        &mdash; are automatically generated by the Perl script
        <filename>custom.pl</filename>. Although it is possible to
        change this script to get additional functionality, it's
        usually better to do that through inheritance.</para>

        <para>A regular user may find it helpful to change the the
        limit on the maximum number of SSQLS data members allowed.
        It's 25 out of the box. A smaller value may speed up
        compile time, or you may require a higher value because
        you have more complex tables than that. Simply change the
        <varname>max_data_members</varname> variable at the top of
        <filename>custom.pl</filename> and say <command>make</command>.
        The limit for Visual C++ is 31, according to one report. There
        doesn't seem to be a practical limit with GCC 3.3 at least:
        I set the limit to 100 and the only thing that happened
        is that custom-macros.h went from 1.3 MB to 18 MB and the
        build time for <filename>examples/custom.*</filename> got a
        lot longer.</para>
    </sect2>

    <sect2>
        <title>SSQLS and BLOB Columns</title>

        <para>It takes special care to use SSQLS with BLOB
        columns. It's safest to declare the SSQLS field as of
        type <classname>mysqlpp::sql_blob</classname>. This
        is currently a typedef alias for <ulink type="classref"
        url="ColData__Tmpl">ColData</ulink>, which is the form the
        data is in just before the SSQLS mechanism populates the
        structure. Thus, when the data is copied from the internal
        MySQL++ data structures into your SSQLS, you get a direct
        copy of the <classname>ColData</classname> object's contents,
        without interference.</para>

        <para>Because <classname>ColData</classname> derives
        from <classname>std::string</classname> and C++
        strings handle binary data just fine, you might think
        you can use <classname>std::string</classname> instead
        of <classname>sql_blob</classname>, but the current
        design of <classname>ColData</classname> converts to
        <classname>std::string</classname> via a C string. As a
        result, the BLOB data is truncated at the first embedded
        null character during population of the SSQLS. There's
        no way to fix that without completely redesigning either
        <classname>ColData</classname> or the SSQLS mechanism.</para>

        <para>The <classname>sql_blob</classname> typedef may be
        changed to alias a different type in the future, so using it
        instead of <classname>ColData</classname> ensures that your
        code tracks these library changes automatically. Besides,
        <classname>ColData</classname> is only intended to be an
        internal mechanism within MySQL++. The only reason the layering
        is so thin here is because it's the only way to prevent BLOB
        data from being corrupted while staying within the current
        library interface design.</para>

        <para>You can see this technique in action in the
        <filename>cgi_jpeg</filename> example:</para>

        <programlisting><xi:include href="cgi_jpeg.txt" parse="text"
        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
    </sect2>
</sect1>


<sect1 id="unicode" xreflabel="Using Unicode with MySQL++">
    <title>Using Unicode with MySQL++</title>

    <sect2>
        <title>A Short History of Unicode</title>
        <subtitle>...with a focus on relevance to MySQL++</subtitle>

        <para>In the old days, computer operating systems only
        dealt with 8-bit character sets. That only allows for 256
        possible characters, but the modern Western languages have
        more characters combined than that alone. Add in all the
        other languages of the world plus the various symbols people
        use in writing, and you have a real mess!</para>

        <para>Since no standards body held sway over things like
        international character encoding in the early days of
        computing, many different character sets were invented. These
        character sets weren't even standardized between operating
        systems, so heaven help you if you needed to move localized
        Greek text on a DOS box to a Russian Macintosh! The only
        way we got any international communication done at all was
        to build standards on top of the common 7-bit ASCII subset.
        Either people used approximations like a plain "c" instead
        of the French "&ccedil;", or they invented things like
        HTML entities ("&amp;ccedil;" in this case) to encode these
        additional characters using only 7-bit ASCII.</para>

        <para>Unicode solves this problem. It encodes every character
        used for writing in the world, using up to 4 bytes per
        character. The subset covering the most economically valuable
        cases takes two bytes per character, so most Unicode-aware
        programs deal in 2-byte characters, for efficiency.</para>

        <para>Unfortunately, Unicode was invented about two decades
        too late for Unix and C. Those decades of legacy created an
        immense inertia preventing a widespread move away from 8-bit
        characters. MySQL and C++ come out of these older traditions,
        and so they share the same practical limitations. MySQL++
        doesn't have a reason to do anything more than just pass
        data along unchanged, so you still need to be aware of these
        underlying issues.</para>

        <para>During the development of the <ulink
        url="http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs">Plan
        9</ulink> operating system (a kind
        of successor to Unix) Ken Thompson <ulink
        url="http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt">invented</ulink>
        the <ulink url="http://en.wikipedia.org/wiki/UTF-8">UTF-8
        encoding</ulink>. UTF-8 is a superset of 7-bit ASCII and
        is compatible with C strings, since it doesn't use 0 bytes
        anywhere as multi-byte Unicode encodings do. As a result,
        many programs that deal in text will cope with UTF-8 data
        even though they have no explicit support for UTF-8. (Follow
        the last link above to see how the design of UTF-8 allows
        this.) Thus, when explicit support for Unicode was added in
        MySQL v4.1, they chose to make UTF-8 the native encoding,
        to preserve backward compatibility with programs that had no
        Unicode support.</para>
    </sect2>


    <sect2>
        <title>Unicode on Unixy Systems</title>

        <para>Linux and Unix have system-wide UTF-8 support these
        days. If your operating system is of 2001 or newer vintage,
        it probably has such support.</para>

        <para>On such a system, the terminal I/O code understands
        UTF-8 encoded data, so your program doesn't require any
        special code to correctly display a UTF-8 string. If you
        aren't sure whether your system supports UTF-8 natively,
        just run the <filename>simple1</filename> example: if the
        first item has two high-ASCII characters in place of the
        "&uuml;" in "N&uuml;rnberger Brats", you know it's not
        handling UTF-8.</para>

        <para>If your Unix doesn't support UTF-8 natively, it likely
        doesn't support any form of Unicode at all, for the historical
        reasons I gave above. Therefore, you will have to convert the
        UTF-8 data to the local 8-bit character set. The standard Unix
        function <function>iconv()</function> can help here. If your
        system doesn't have the <function>iconv()</function> facility,
        there is <ulink url="http://www.gnu.org/software/libiconv/">a
        free implementation</ulink> available from the GNU
        Project. Another library you might check out is IBM's <ulink
        url="http://icu.sourceforge.net/">ICU</ulink>. This is
        rather heavy-weight, so if you just need basic conversions,
        <function>iconv()</function> should suffice.</para>
    </sect2>


    <sect2>
        <title>Unicode on Windows</title>

        <para>Each Windows API function that takes a string actually
        comes in two versions. One version supports only 1-byte "ANSI"
        characters (a superset of ASCII), so they end in 'A'. Windows
        also supports the 2-byte subset of Unicode called <ulink
        url="http://en.wikipedia.org/wiki/UCS-2">UCS-2</ulink>.
        Some call these "wide" characters,
        so the other set of functions end in 'W'. The <function><ulink
        url="http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/dialogboxreference/dialogboxfunctions/messagebox.asp">MessageBox</ulink>()</function>
        API, for instance, is actually a macro, not a real function. If
        you define the <symbol>UNICODE</symbol> macro when building
        your program, the <function>MessageBox()</function> macro
        evaluates to <function>MessageBoxW()</function>; otherwise,
        to <function>MessageBoxA()</function>.</para>

        <para>Since MySQL uses the UTF-8 Unicode encoding and Windows
        uses UCS-2, you must convert data when passing text between
        MySQL++ and the Windows API. Since there's no point in trying
        for portability &mdash; no other OS I'm aware of uses UCS-2
        &mdash; you might as well use platform-specific functions
        to do this translation. Since version 2.2.2, MySQL++ ships
        with two Visual C++ specific examples showing how to do this
        in a GUI program.  (In earlier versions of MySQL++, we did
        Unicode conversion in the console mode programs, but this
        was unrealistic.)</para>

        <para>How you handle Unicode data depends on whether you're
        using the native Windows API, or the newer .NET API. First,
        the native case:</para>

        <programlisting>
// Convert a C string in UTF-8 format to UCS-2 format.
void ToUCS2(LPTSTR pcOut, int nOutLen, const char* kpcIn)
{
    MultiByteToWideChar(CP_UTF8, 0, kpcIn, -1, pcOut, nOutLen);
}

// Convert a UCS-2 string to C string in UTF-8 format.
void ToUTF8(char* pcOut, int nOutLen, LPCWSTR kpcIn)
{
    WideCharToMultiByte(CP_UTF8, 0, kpcIn, -1, pcOut, nOutLen, 0, 0);
}</programlisting>

        <para>These functions leave out some important error checking,
        so see <filename>examples/vstudio/mfc/mfc_dlg.cpp</filename>
        for the complete version.</para>

        <para>If you're building a .NET application (such as, perhaps,
        because you're using Windows Forms), it's better to use the
        .NET libraries for this:</para>

        <programlisting>
// Convert a C string in UTF-8 format to a .NET String in UCS-2 format.
String^ ToUCS2(const char* utf8)
{
    return gcnew String(utf8, 0, strlen(utf8), System::Text::Encoding::UTF8);
}

// Convert a .NET String in UCS-2 format to a C string in UTF-8 format.
System::Void ToUTF8(char* pcOut, int nOutLen, String^ sIn)
{
    array&lt;Byte&gt;^ bytes = System::Text::Encoding::UTF8->GetBytes(sIn);
    nOutLen = Math::Min(nOutLen - 1, bytes->Length);
    System::Runtime::InteropServices::Marshal::Copy(bytes, 0,
        IntPtr(pcOut), nOutLen);
    pcOut[nOutLen] = '\0';
}</programlisting>

        <para>Unlike the native API versions, these examples are
        complete, since the .NET platform handles a lot of things
        behind the scenes for us. We don't need any error-checking
        code for such simple routines.</para>

        <para>All of this assumes you're using Windows NT or one of
        its direct descendants: Windows 2000, Windows XP, Windows
        Vista, or any "Server" variant of Windows. Windows 95 and its
        descendants (98, ME, and CE) do not support UCS-2. They still
        have the 'W' APIs for compatibility, but they just smash the
        data down to 8-bit and call the 'A' version for you.</para>
    </sect2>


    <sect2>
        <title>For More Information</title>
            <para>The <ulink
            url="http://www.unicode.org/faq/">Unicode
            FAQs</ulink> page has copious information on
            this complex topic.</para>

            <para>When it comes to Unix
            and UTF-8 specific items, the <ulink
            url="http://www.cl.cam.ac.uk/~mgk25/unicode.html">UTF-8
            and Unicode FAQ for Unix/Linux</ulink> is a
            quicker way to find basic information.</para>
        </sect2>
</sect1>


<sect1 id="capilimits">
    <title>Important Underlying C API Limitations</title>

    <para>Since MySQL++ is built on top of the MySQL C API
    (libmysqlclient), it shares all of its limitations. The
    following points out some of these limitations that frequently
    bite newbies. Some of these may be papered over at the MySQL++
    layer in future releases, but it's best to write your program as
    if they were permanent fixtures of the universe.</para>

    <orderedlist>
        <listitem>
            <para><emphasis>Only one active query per
            connection.</emphasis> This one bites MySQL++ newbies most
            often in multithreaded programs.  If the program has only
            one Connection object and each thread gets their Query
            objects from it, it's inevitable that one of those query
            objects will try to execute while another query is already
            running on that single connection. The safest course is
            to have a separate Connection object per thread, and for
            your code to get Query objects in a thread only from that
            thread's Connection object. Alternately, you can confine
            MySQL database access to a single thread.</para>
        </listitem>

        <listitem>
            <para><emphasis>You must consume all rows from a query
            before you can start a new query.</emphasis> This one
            bites MySQL++ newbies most often when they try code
            like this:</para>

            <programlisting>
Connection c(...);
Query q = c.query();
Result r1 = q.use("select garbage from plink where foobie='tamagotchi'");
Result r2 = q.use("select blah from bonk where bletch='smurf'");</programlisting>

            <para>This will fail because a "use" query consumes rows
            only on demand, so the MySQL server is still keeping
            information around about the first query when the second
            one comes in on the connection.  When you try the second
            query, MySQL++ will throw an exception containing an
            obscure MySQL C API error message about "commands out
            of sync".</para>

            <para>This is not the only situation where this can happen,
            but all of these issues boil down to the fact that MySQL
            requires that certain operations complete before you can
            start a new one.</para>
        </listitem>

        <listitem>
            <para><emphasis>The <classname>Result</classname> object
            must outlive the use of any <classname>Row</classname>
            objects it returns.</emphasis> This is because the
            <classname>Row</classname> objects refer back to the
            <classname>Result</classname> object that created them for
            certain data. (Field names, for example.) MySQL does this
            for efficiency, because there is some information about a
            row that is the same for all rows in a result set. We could
            avoid this in MySQL++ by making redundant copies of this
            data for each row, but that would be quite wasteful.</para>

            <para>Beware of some of the more obscure ways this can
            happen. For example:</para>

            <programlisting>
Connection c(...);
Query q = c.query();
Result res = q.store("...");
Row row = res.at(0);
res = q.store("...");</programlisting>

            <para>At this point, the <varname>row</varname> variable's
            contents are likely no longer usable. The program may run,
            but the row object will use data (field names, etc.) from
            the second query, not the first.</para>
        </listitem>
    </orderedlist>
</sect1>


<sect1 id="breakages">
    <title>Incompatible Library Changes</title>

    <para>This chapter documents those library changes since the
    epochal 1.7.9 release that break end-user programs. You can dig
    this stuff out of the ChangeLog, but the ChangeLog focuses more
    on explaining and justifying the facets of each change, while
    this section focuses on how to migrate your code between these
    library versions.</para>

    <para>Since pure additions do not break programs, those changes
    are still documented only in the ChangeLog.</para>


    <sect2>
        <title>API Changes</title>

        <para>This section documents files, functions, methods and
        classes that were removed or changed in an incompatible
        way. If your program uses the changed item, you will have to
        change something in your program to get it to compile after
        upgrading to each of these versions.</para>

        <sect3>
            <title>v1.7.10</title>

            <para>Removed <methodname>Row::operator[]()</methodname>
            overloads except the one for <type>size_type</type>,
            and added <methodname>Row::lookup_by_name()</methodname>
            to provide the "subscript by string" functionality.
            In practical terms, this change means that the
            <varname>row["field"]</varname> syntax no longer works; you
            must use the new <methodname>lookup_by_name</methodname>
            method instead.</para>

            <para>Renamed the generated library on POSIX
            systems from <filename>libsqlplus</filename> to
            <filename>libmysqlpp</filename>.</para>
        </sect3>


        <sect3>
            <title>v1.7.19</title>

            <para>Removed
            <methodname>SQLQuery::operator=()</methodname>, and the
            same for its <classname>Query</classname> subclass. Use
            the copy constructor instead, if you need to copy one
            query to another query object.</para>
        </sect3>


        <sect3>
            <title>v1.7.20</title>

            <para>The library used to have two names for many core
            classes: a short one, such as <classname>Row</classname>
            and a longer one, <classname>MysqlRow</classname>. The
            library now uses the shorter names exclusively.</para>

            <para>All symbols within MySQL++ are in the
            <filename>mysqlpp</filename> namespace now if you
            use the new <filename>mysql++.h</filename> header. If
            you use the older <filename>sqlplus.hh</filename> or
            <filename>mysql++.hh</filename> headers, these symbols
            are hoist up into the global namespace. The older headers
            cause the compiler to emit warnings if you use them,
            and they will go away someday.</para>
        </sect3>

        
        <sect3>
            <title>v2.0.0</title>

            <sect4>
                <title>Connection class changes</title>

                <itemizedlist>
                    <listitem><para><methodname>Connection::create_db()</methodname>
                    and <methodname>drop_db()</methodname> return
                    <symbol>true</symbol> on success. They
                    returned <symbol>false</symbol> in
                    v1.7.<emphasis>x</emphasis>!  This change will
                    only affect your code if you have exceptions
                    disabled.</para></listitem>

                    <listitem><para>Renamed
                    <methodname>Connection::real_connect()</methodname>
                    to <methodname>connect()</methodname>, made several
                    more of its parameters default, and removed the
                    old <methodname>connect()</methodname> method, as
                    it's now a strict subset of the new one. The only
                    practical consequence is that if your program was
                    using <methodname>real_connect()</methodname>,
                    you will have to change it to
                    <methodname>connect()</methodname>.</para></listitem>

                    <listitem><para>Replaced
                    <methodname>Connection::read_option()</methodname>
                    with new <methodname>set_option()</methodname>
                    mechanism. In addition to changing the name,
                    programs using this function will have to use
                    the new <classname>Connection::Option</classname>
                    enumerated values, accept a <symbol>true</symbol>
                    return value as meaning success instead of 0,
                    and use the proper argument type. Regarding the
                    latter, <methodname>read_option()</methodname>
                    took a <type>const char*</type> argument, but
                    because it was just a thin wrapper over the
                    MySQL C API function <ulink url="mysql-options"
                    type="mysqlapi"/>, the actual value being pointed
                    to could be any of several types. This new
                    mechanism is properly type-safe.</para></listitem>
                </itemizedlist>
            </sect4>


            <sect4>
                <title>Exception-related changes</title>

                <itemizedlist>
                    <listitem><para>Classes
                    <classname>Connection</classname>,
                    <classname>Query</classname>,
                    <classname>Result</classname>,
                    <classname>ResUse</classname>, and
                    <classname>Row</classname> now derive from <ulink
                    type="classref" url="OptionalExceptions"/>
                    which gives these classes a common interface
                    for disabling exceptions. In addition, almost
                    all of the per-method exception-disabling
                    flags were removed. The preferred method
                    for disabling exceptions on these objects
                    is to create an instance of the new <ulink
                    type="classref" url="NoExceptions"/> class
                    on the stack, which disables exceptions on an
                    <classname>OptionalExceptions</classname> subclass
                    as long as the <classname>NoExceptions</classname>
                    instance is in scope. You can instead call
                    <methodname>disable_exceptions()</methodname>
                    on any of these objects, but if you only want
                    them disabled temporarily, it's easy to forget
                    to re-enable them later.</para></listitem>

                    <listitem><para>In the previous version of
                    MySQL++, those classes that supported optional
                    exceptions that could create instances of other
                    such classes were supposed to pass this flag
                    on to their children. That is, if you created
                    a <classname>Connection</classname> object
                    with exceptions enabled, and then asked it to
                    create a <classname>Query</classname> object,
                    the <classname>Query</classname> object also had
                    exceptions disabled. The problem is, this didn't
                    happen in all cases where it should have in v1.7.
                    This bug is fixed in v2.0. If your program begins
                    crashing due to uncaught exceptions after upgrading
                    to v2.0, this is the most likely cause. The most
                    expeditious fix in this situation is to use the
                    new <classname>NoExceptions</classname> feature to
                    return these code paths to the v1.7 behavior. A
                    better fix is to rework your program to avoid or
                    deal with the new exceptions.</para></listitem>

                    <listitem><para>All custom MySQL++ exceptions
                    now derive from the new <ulink type="classref"
                    url="Exception"/> interface.  The practical
                    upshot of this is that the variability
                    between the various exception types has been
                    eliminated. For instance, to get the error
                    string, the <classname>BadQuery</classname>
                    exception had a string member called
                    <varname>error</varname> plus a method called
                    <methodname>what()</methodname>.  Both did the same
                    thing, and the <methodname>what()</methodname>
                    method is more common, so the error string was
                    dropped from the interface. None of the example
                    programs had to be changed to work with the new
                    exceptions, so if your program handles MySQL++
                    exceptions the same way they do, your program
                    won't need to change, either.</para></listitem>

                    <listitem><para>Renamed
                    <classname>SQLQueryNEParams</classname> exception
                    to <classname>BadParamCount</classname> to match
                    style of other exception names.</para></listitem>

                    <listitem><para>Added
                    <ulink type="classref" url="BadOption"/>,
                    <ulink type="classref" url="ConnectionFailed"/>,
                    <ulink type="classref" url="DBSelectionFailed"/>,
                    <ulink type="classref" url="EndOfResults"/>,
                    <ulink type="classref" url="EndOfResultSets"/>,
                    <ulink type="classref" url="LockFailed"/>, and
                    <ulink type="classref" url="ObjectNotInitialized"/>
                    exception types, to fix overuse of
                    <classname>BadQuery</classname>.  Now the latter
                    is used only for errors on query execution. If
                    your program has a "catch-all" block taking
                    a <classname>std::exception</classname> for
                    each try block containing MySQL++ statements,
                    you probably won't need to change your
                    program. Otherwise, the new exceptions will
                    likely show up as program crashes due to unhandled
                    exceptions.</para></listitem>
                </itemizedlist>
            </sect4>


            <sect4>
                <title>Query class changes</title>

                <itemizedlist>
                    <listitem><para>In previous versions,
                    <classname>Connection</classname>
                    had a querying interface similar to class
                    <classname>Query</classname>'s.  These methods were
                    intended only for <classname>Query</classname>'s
                    use; no example ever used this interface directly,
                    so no end-user code is likely to be affected by
                    this change.</para></listitem>

                    <listitem><para>A more likely problem
                    arising from the above change is code that
                    tests for query success by calling the
                    <classname>Connection</classname> object's
                    <methodname>success()</methodname> method or by
                    casting it to <type>bool</type>.  This will now
                    give misleading results, because queries no longer
                    go through the <classname>Connection</classname>
                    object. Class <classname>Query</classname> has
                    the same success-testing interface, so use it
                    instead.</para></listitem>

                    <listitem><para><classname>Query</classname>
                    now derives from
                    <classname>std::ostream</classname> instead of
                    <classname>std::stringstream</classname>.</para></listitem>
                </itemizedlist>
            </sect4>


            <sect4>
                <title>Result/ResUse class changes</title>

                <itemizedlist>
                    <listitem><para>Renamed
                    <methodname>ResUse::mysql_result()</methodname>
                    to <methodname>raw_result()</methodname> so it's
                    database server neutral.</para></listitem>

                    <listitem><para>Removed
                    <methodname>ResUse::eof()</methodname>,
                    as it wrapped the deprecated and
                    unnecessary MySQL C API function <ulink
                    url="mysql-eof" type="mysqlapi"/>. See
                    the <filename>simple3</filename> and
                    <filename>usequery</filename> examples to see
                    the proper way to test for the end of a result
                    set.</para></listitem>
                </itemizedlist>
            </sect4>


            <sect4>
                <title>Row class changes</title>

                <itemizedlist>
                    <listitem><para>Removed "field name" form of
                    <methodname>Row::field_list()</methodname>.
                    It was pointless.</para></listitem>

                    <listitem><para><classname>Row</classname>
                    subscripting works more
                    like v1.7.9: one can subscript a
                    <classname>Row</classname> with a string (e.g.
                    <methodname>row["myfield"]</methodname>), or with
                    an integer (e.g.  <methodname>row[5]</methodname>).
                    <methodname>lookup_by_name()</methodname> was
                    removed. Because <methodname>row[0]</methodname>
                    is ambiguous (0 could mean the first field, or be
                    a null pointer to <type>const char*</type>), there
                    is now <methodname>Row::at()</methodname>, which
                    can look up any field by index.</para></listitem>
                </itemizedlist>
            </sect4>


            <sect4>
                <title>Miscellaneous changes</title>

                <itemizedlist>
                    <listitem><para>Where possible, all distributed
                    Makefiles only build dynamic libraries. (Shared
                    objects on most Unices, DLLs on Windows,
                    etc.) Unless your program is licensed under
                    the GPL or LGPL, you shouldn't have been using
                    the static libraries from previous versions
                    anyway.</para></listitem>

                    <listitem><para>Removed the backwards-compatibility
                    headers <filename>sqlplus.hh</filename> and
                    <filename>mysql++.hh</filename>.  If you were
                    still using these, you will have to change
                    to <filename>mysql++.h</filename>, which
                    will put all symbols in <symbol>namespace
                    mysqlpp</symbol>.</para></listitem>

                    <listitem><para>Can no longer use arrow operator
                    (<symbol>-></symbol>) on the iterators
                    into the <classname>Fields</classname>,
                    <classname>Result</classname>
                    and <classname>Row</classname>
                    containers.</para></listitem>
                </itemizedlist>
            </sect4>
        </sect3>

        <sect3>
            <title>v2.2.0</title>

            <para>Code like this will have to change:</para>

            <programlisting>
Query q = con.query();
q &lt;&lt; "delete from mytable where myfield=%0:myvalue";
q.parse();
q.def["myvalue"] = some_value;
q.execute();</programlisting>

            <para>...to something more like this:</para>

            <programlisting>
Query q = con.query();
q &lt;&lt; "delete from mytable where myfield=%0";
q.parse();
q.execute(some_value);</programlisting>

            <para>The first code snippet abuses the default template
            query parameter mechanism (<varname>Query::def</varname>)
            to fill out the template instead of using one of the
            overloaded forms of <methodname>execute()</methodname>,
            <methodname>store()</methodname> or
            <methodname>use()</methodname> taking one or more
            <classname>SQLString</classname> parameters.  The purpose
            of <varname>Query::def</varname> is to allow for default
            template parameters over multiple queries. In the first
            snippet above, there is only one parameter, so in order
            to justify the use of template queries in the first
            place, it must be changing with each query. Therefore,
            it isn't really a "default" parameter at all. We did not
            make this change maliciously, but you can understand why
            we are not in any hurry to restore this "feature".</para>

            <para>(Incidentally, this change was made to allow better
            support for BLOB columns.)</para>
        </sect3>


        <sect3>
            <title>v2.3.0</title>

            <para><methodname>Connection::set_option()</methodname>
            calls now set the connection option immediately, instead
            of waiting until just before the connnection is actually
            established. Code that relied on the old behavior could see
            unhandled exceptions, since option setting errors are now
            thrown from a different part of the code. You want to wrap
            the actual <methodname>set_option()</methodname> call now,
            not <methodname>Connection::connect()</methodname></para>

            <para><classname>FieldNames</classname> and
            <classname>FieldTypes</classname> are no longer exported
            from the library. If you are using these classes directly
            from Visual C++ or MinGW, your code won't be able to
            dynamically link to a DLL version of the library any
            more. These are internal classes, however, so no one
            should be using them directly.</para>
        </sect3>
    </sect2>


    <sect2>
        <title>ABI Changes</title>

        <para>This section documents those library changes that require
        you to rebuild your program so that it will link with the
        new library.  Most of the items in the previous section are
        also ABI changes, but this section is only for those items
        that shouldn't require any code changes in your program.</para>

        <para>If you were going to rebuild your program after
        installing the new library anyway, you can probably ignore
        this section.</para>


        <sect3>
            <title>v1.7.18</title>

            <para>The <classname>Query</classname> classes now subclass
            from <classname>stringstream</classname> instead of the
            deprecated <classname>strstream</classname>.</para>
        </sect3>


        <sect3>
            <title>v1.7.19</title>

            <para>Fixed several <type>const</type>-incorrectnesses
            in the <classname>Query</classname> classes.</para>
        </sect3>


        <sect3>
            <title>v1.7.22</title>

            <para>Removed "reset query" parameters from several
            <classname>Query</classname> class members. This is not
            an API change, because the parameters were given default
            values, and the library would ignore any value other than
            the default. So, any program that tried to make them take
            another value wouldn't have worked anyway.</para>
        </sect3>


        <sect3>
            <title>v1.7.24</title>

            <para>Some freestanding functions didn't get moved into
            <symbol>namespace mysqlpp</symbol> when that namespace was
            created. This release fixed that. It doesn't affect the
            API if your program's C++ source files say <symbol>using
            namespace mysqlpp</symbol> within them.</para>
        </sect3>


        <sect3>
            <title>v2.0.0</title>

            <para>Removed <methodname>Connection::infoo()</methodname>.
            (I'd call this an API change if I thought there were any
            programs out there actually using this...)</para>

            <para>Collapsed the <classname>Connection</classname>
            constructor taking a bool (for setting the throw_exceptions
            flag) and the default constructor into a single constructor
            using a default for the parameter.</para>

            <para>Classes <classname>Connection</classname> and
            <classname>Query</classname> are now derived from the
            <classname>Lockable</classname> interface, instead of
            implementing their own lock/unlock functions.</para>

            <para>In several instances, functions that took
            objects by value now take them by const reference,
            for efficiency.</para>

            <para>Merged <classname>SQLQuery</classname> class's
            members into class <classname>Query</classname>.</para>

            <para>Merged <classname>RowTemplate</classname> class's
            members into class <classname>Row</classname>.</para>

            <para>Reordered member variable declarations in some
            classes. The most common instance is when the private
            section was declared before the public section; it is now
            the opposite way. This can change the object's layout
            in memory, so a program linking to the library must be
            rebuilt.</para>

            <para>Simplified the date and time class hierarchy.
            <ulink type="structref" url="Date"/> used to
            derive from <classname>mysql_date</classname>,
            <ulink type="structref" url="Time"/> used to derive
            from <classname>mysql_time</classname>, and <ulink
            type="structref" url="DateTime"/> used to derive from
            both of those.  All three of these classes used to derive
            from <classname>mysql_dt_base</classname>.  All of the
            <classname>mysql_*</classname> classes' functionality and
            data has been folded into the leaf classes, and now the
            only thing shared between them is their dependence on the
            <ulink type="structref" url="DTbase"/> template. Since
            the leaf classes' interface has not changed and end-user
            code shouldn't have been using the other classes, this
            shouldn't affect the API in any practical way.</para>

            <para><classname>mysql_type_info</classname> now always
            initializes its private <varname>num</varname> member.
            Previously, this would go uninitialized if you used
            the default constructor. Now there is no default
            ctor, but the ctor taking one argument (which sets
            <varname>num</varname>) has a default.</para>
        </sect3>
    </sect2>
</sect1>


<sect1 id="licenses">
    <title>Licensing</title>

    <para>The primary copyright holders on the MySQL++ library and
    its documentation are Kevin Atkinson (1998), MySQL AB (1999
    through 2001) and Educational Technology Resources, Inc. (2004
    through the date of this writing). There are other contributors,
    who also retain copyrights on their additions; see the ChangeLog
    file in the MySQL++ distribution tarball for details.</para>

    <para>The MySQL++ library and its Reference Manual are released
    under the GNU Lesser General Public License (LGPL), reproduced
    below.</para>
    
    <para>The MySQL++ User Manual &mdash; excepting some example
    code from the library reproduced within it &mdash; is offered
    under a license closely based on the Linux Documentation Project
    License (LDPL) v2.0, included below. (The MySQL++ documentation
    isn't actually part of the Linux Documentation Project, so
    the main changes are to LDP-related language. Also, generic
    language such as "author's (or authors')" has been replaced
    with specific language, because the license applies to only
    this one document.)</para>

    <para>These licenses basically state that you are free to use,
    distribute and modify these works, whether for personal or
    commercial purposes, as long as you grant the same rights to
    those you distribute the works to, whether you changed them or
    not. See the licenses below for full details.</para>


<?hard-pagebreak?>
<sect2>
    <title>GNU Lesser General Public License</title>
    <subtitle>Version 2.1, February 1999</subtitle>

    <para>Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA Everyone is
    permitted to copy and distribute verbatim copies of this license
    document, but changing it is not allowed.</para>

    <para>[This is the first released version of the Lesser GPL.
    It also counts as the successor of the GNU Library Public License,
    version 2, hence the version number 2.1.]</para>

    <sect3>
        <title>Preamble</title>

        <para>The licenses for most software are designed to take
        away your freedom to share and change it.  By contrast, the
        GNU General Public Licenses are intended to guarantee your
        freedom to share and change free software--to make sure the
        software is free for all its users.</para>

        <para>This license, the Lesser General Public License, applies
        to some specially designated software packages--typically
        libraries--of the Free Software Foundation and other authors
        who decide to use it.  You can use it too, but we suggest
        you first think carefully about whether this license or the
        ordinary General Public License is the better strategy to use
        in any particular case, based on the explanations below.</para>

        <para>When we speak of free software, we are referring to
        freedom of use, not price.  Our General Public Licenses are
        designed to make sure that you have the freedom to distribute
        copies of free software (and charge for this service if you
        wish); that you receive source code or can get it if you want
        it; that you can change the software and use pieces of it in
        new free programs; and that you are informed that you can do
        these things.</para>

        <para>To protect your rights, we need to make restrictions
        that forbid distributors to deny you these rights or to ask
        you to surrender these rights.  These restrictions translate
        to certain responsibilities for you if you distribute copies
        of the library or if you modify it.</para>

        <para>For example, if you distribute copies of the library,
        whether gratis or for a fee, you must give the recipients all
        the rights that we gave you.  You must make sure that they,
        too, receive or can get the source code.  If you link other
        code with the library, you must provide complete object
        files to the recipients, so that they can relink them
        with the library after making changes to the library and
        recompiling it.  And you must show them these terms so they
        know their rights.</para>

        <para>We protect your rights with a two-step method: (1)
        we copyright the library, and (2) we offer you this license,
        which gives you legal permission to copy, distribute and/or
        modify the library.</para>

        <para>To protect each distributor, we want to make it very
        clear that there is no warranty for the free library.  Also,
        if the library is modified by someone else and passed on, the
        recipients should know that what they have is not the original
        version, so that the original author's reputation will not be
        affected by problems that might be introduced by others.</para>

        <para>Finally, software patents pose a constant threat to the
        existence of any free program.  We wish to make sure that a
        company cannot effectively restrict the users of a free program
        by obtaining a restrictive license from a patent holder.
        Therefore, we insist that any patent license obtained for
        a version of the library must be consistent with the full
        freedom of use specified in this license.</para>

        <para>Most GNU software, including some libraries, is covered
        by the ordinary GNU General Public License.  This license,
        the GNU Lesser General Public License, applies to certain
        designated libraries, and is quite different from the ordinary
        General Public License.  We use this license for certain
        libraries in order to permit linking those libraries into
        non-free programs.</para>

        <para>When a program is linked with a library, whether
        statically or using a shared library, the combination of
        the two is legally speaking a combined work, a derivative of
        the original library.  The ordinary General Public License
        therefore permits such linking only if the entire combination
        fits its criteria of freedom.  The Lesser General Public
        License permits more lax criteria for linking other code with
        the library.</para>

        <para>We call this license the "Lesser" General Public License
        because it does Less to protect the user's freedom than the
        ordinary General Public License.  It also provides other
        free software developers Less of an advantage over competing
        non-free programs.  These disadvantages are the reason we
        use the ordinary General Public License for many libraries.
        However, the Lesser license provides advantages in certain
        special circumstances.</para>

        <para>For example, on rare occasions, there may be a special
        need to encourage the widest possible use of a certain
        library, so that it becomes a de-facto standard.  To achieve
        this, non-free programs must be allowed to use the library.
        A more frequent case is that a free library does the same job
        as widely used non-free libraries.  In this case, there is
        little to gain by limiting the free library to free software
        only, so we use the Lesser General Public License.</para>

        <para>In other cases, permission to use a particular library
        in non-free programs enables a greater number of people to
        use a large body of free software.  For example, permission
        to use the GNU C Library in non-free programs enables many
        more people to use the whole GNU operating system, as well
        as its variant, the GNU/Linux operating system.</para>

        <para>Although the Lesser General Public License is Less
        protective of the users' freedom, it does ensure that the
        user of a program that is linked with the Library has the
        freedom and the wherewithal to run that program using a
        modified version of the Library.</para>

        <para>The precise terms and conditions for copying,
        distribution and modification follow.  Pay close attention
        to the difference between a "work based on the library" and
        a "work that uses the library".  The former contains code
        derived from the library, whereas the latter must be combined
        with the library in order to run.</para>
    </sect3>


    <sect3>
        <title>GNU LESSER GENERAL PUBLIC LICENSE</title>
        <subtitle>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
            MODIFICATION</subtitle>

        <para>0. This License Agreement applies to any software
        library or other program which contains a notice placed by
        the copyright holder or other authorized party saying it
        may be distributed under the terms of this Lesser General
        Public License (also called "this License").  Each licensee
        is addressed as "you".</para>

        <para>A "library" means a collection of software functions
        and/or data prepared so as to be conveniently linked with
        application programs (which use some of those functions and
        data) to form executables.</para>

        <para>The "Library", below, refers to any such software
        library or work which has been distributed under these terms.
        A "work based on the Library" means either the Library or any
        derivative work under copyright law: that is to say, a work
        containing the Library or a portion of it, either verbatim
        or with modifications and/or translated straightforwardly
        into another language.  (Hereinafter, translation is included
        without limitation in the term "modification".)</para>

        <para>"Source code" for a work means the preferred form
        of the work for making modifications to it.  For a library,
        complete source code means all the source code for all modules
        it contains, plus any associated interface definition files,
        plus the scripts used to control compilation and installation
        of the library.</para>

        <para>Activities other than copying, distribution and
        modification are not covered by this License; they are outside
        its scope.  The act of running a program using the Library
        is not restricted, and output from such a program is covered
        only if its contents constitute a work based on the Library
        (independent of the use of the Library in a tool for writing
        it).  Whether that is true depends on what the Library does
        and what the program that uses the Library does.</para>

        <para>1. You may copy and distribute verbatim copies of the
        Library's complete source code as you receive it, in any
        medium, provided that you conspicuously and appropriately
        publish on each copy an appropriate copyright notice and
        disclaimer of warranty; keep intact all the notices that
        refer to this License and to the absence of any warranty;
        and distribute a copy of this License along with the
        Library.</para>

        <para>You may charge a fee for the physical act of transferring
        a copy, and you may at your option offer warranty protection
        in exchange for a fee.</para>

        <para>2. You may modify your copy or copies of the Library or
        any portion of it, thus forming a work based on the Library,
        and copy and distribute such modifications or work under the
        terms of Section 1 above, provided that you also meet all of
        these conditions:</para>

        <blockquote>
            <para>a) The modified work must itself be a software
            library.</para>

            <para>b) You must cause the files modified to carry
            prominent notices stating that you changed the files and
            the date of any change.</para>

            <para>c) You must cause the whole of the work to be
            licensed at no charge to all third parties under the
            terms of this License.</para>

            <para>d) If a facility in the modified Library refers
            to a function or a table of data to be supplied by an
            application program that uses the facility, other than as
            an argument passed when the facility is invoked, then you
            must make a good faith effort to ensure that, in the event
            an application does not supply such function or table,
            the facility still operates, and performs whatever part
            of its purpose remains meaningful.</para>

            <para>(For example, a function in a library to compute
            square roots has a purpose that is entirely well-defined
            independent of the application.  Therefore, Subsection 2d
            requires that any application-supplied function or table
            used by this function must be optional: if the application
            does not supply it, the square root function must still
            compute square roots.)</para>
        </blockquote>

        <para>These requirements apply to the modified work as a whole.
        If identifiable sections of that work are not derived from
        the Library, and can be reasonably considered independent and
        separate works in themselves, then this License, and its terms,
        do not apply to those sections when you distribute them as
        separate works.  But when you distribute the same sections
        as part of a whole which is a work based on the Library,
        the distribution of the whole must be on the terms of this
        License, whose permissions for other licensees extend to the
        entire whole, and thus to each and every part regardless of
        who wrote it.</para>

        <para>Thus, it is not the intent of this section to claim
        rights or contest your rights to work written entirely by
        you; rather, the intent is to exercise the right to control
        the distribution of derivative or collective works based on
        the Library.</para>

        <para>In addition, mere aggregation of another work not
        based on the Library with the Library (or with a work based
        on the Library) on a volume of a storage or distribution
        medium does not bring the other work under the scope of this
        License.</para>

        <para>3. You may opt to apply the terms of the ordinary GNU
        General Public License instead of this License to a given
        copy of the Library.  To do this, you must alter all the
        notices that refer to this License, so that they refer to the
        ordinary GNU General Public License, version 2, instead of
        to this License.  (If a newer version than version 2 of the
        ordinary GNU General Public License has appeared, then you
        can specify that version instead if you wish.)  Do not make
        any other change in these notices.</para>

        <para>Once this change is made in a given copy, it is
        irreversible for that copy, so the ordinary GNU General Public
        License applies to all subsequent copies and derivative works
        made from that copy.</para>

        <para>This option is useful when you wish to copy part
        of the code of the Library into a program that is not a
        library.</para>

        <para>4. You may copy and distribute the Library (or a
        portion or derivative of it, under Section 2) in object code
        or executable form under the terms of Sections 1 and 2 above
        provided that you accompany it with the complete corresponding
        machine-readable source code, which must be distributed under
        the terms of Sections 1 and 2 above on a medium customarily
        used for software interchange.</para>

        <para>If distribution of object code is made by offering access
        to copy from a designated place, then offering equivalent
        access to copy the source code from the same place satisfies
        the requirement to distribute the source code, even though
        third parties are not compelled to copy the source along with
        the object code.</para>

        <para>5. A program that contains no derivative of any portion
        of the Library, but is designed to work with the Library by
        being compiled or linked with it, is called a "work that uses
        the Library".  Such a work, in isolation, is not a derivative
        work of the Library, and therefore falls outside the scope
        of this License.</para>

        <para>However, linking a "work that uses the Library" with
        the Library creates an executable that is a derivative of
        the Library (because it contains portions of the Library),
        rather than a "work that uses the library".  The executable
        is therefore covered by this License.  Section 6 states terms
        for distribution of such executables.</para>

        <para>When a "work that uses the Library" uses material from a
        header file that is part of the Library, the object code for
        the work may be a derivative work of the Library even though
        the source code is not.  Whether this is true is especially
        significant if the work can be linked without the Library,
        or if the work is itself a library.  The threshold for this
        to be true is not precisely defined by law.</para>

        <para>If such an object file uses only numerical parameters,
        data structure layouts and accessors, and small macros and
        small inline functions (ten lines or less in length), then the
        use of the object file is unrestricted, regardless of whether
        it is legally a derivative work.  (Executables containing
        this object code plus portions of the Library will still fall
        under Section 6.)</para>

        <para>Otherwise, if the work is a derivative of the Library,
        you may distribute the object code for the work under the
        terms of Section 6.  Any executables containing that work
        also fall under Section 6, whether or not they are linked
        directly with the Library itself.</para>

        <para>6. As an exception to the Sections above, you may
        also combine or link a "work that uses the Library" with
        the Library to produce a work containing portions of the
        Library, and distribute that work under terms of your choice,
        provided that the terms permit modification of the work for
        the customer's own use and reverse engineering for debugging
        such modifications.</para>

        <para>You must give prominent notice with each copy of the
        work that the Library is used in it and that the Library
        and its use are covered by this License.  You must supply a
        copy of this License.  If the work during execution displays
        copyright notices, you must include the copyright notice for
        the Library among them, as well as a reference directing the
        user to the copy of this License.  Also, you must do one of
        these things:</para>

        <blockquote>
            <para>a) Accompany the work with the complete corresponding
            machine-readable source code for the Library including
            whatever changes were used in the work (which must
            be distributed under Sections 1 and 2 above); and,
            if the work is an executable linked with the Library,
            with the complete machine-readable "work that uses the
            Library", as object code and/or source code, so that the
            user can modify the Library and then relink to produce
            a modified executable containing the modified Library.
            (It is understood that the user who changes the contents
            of definitions files in the Library will not necessarily
            be able to recompile the application to use the modified
            definitions.)</para>

            <para>b) Use a suitable shared library mechanism for
            linking with the Library.  A suitable mechanism is one
            that (1) uses at run time a copy of the library already
            present on the user's computer system, rather than copying
            library functions into the executable, and (2) will
            operate properly with a modified version of the library,
            if the user installs one, as long as the modified version
            is interface-compatible with the version that the work
            was made with.</para>

            <para>c) Accompany the work with a written offer, valid for
            at least three years, to give the same user the materials
            specified in Subsection 6a, above, for a charge no more
            than the cost of performing this distribution.</para>

            <para>d) If distribution of the work is made by offering
            access to copy from a designated place, offer equivalent
            access to copy the above specified materials from the
            same place.</para>

            <para>e) Verify that the user has already received a
            copy of these materials or that you have already sent
            this user a copy.</para>
        </blockquote>

        <para>For an executable, the required form of the "work that
        uses the Library" must include any data and utility programs
        needed for reproducing the executable from it.  However,
        as a special exception, the materials to be distributed need
        not include anything that is normally distributed (in either
        source or binary form) with the major components (compiler,
        kernel, and so on) of the operating system on which the
        executable runs, unless that component itself accompanies
        the executable.</para>

        <para>It may happen that this requirement contradicts the
        license restrictions of other proprietary libraries that do not
        normally accompany the operating system.  Such a contradiction
        means you cannot use both them and the Library together in
        an executable that you distribute.</para>

        <para>7. You may place library facilities that are a work
        based on the Library side-by-side in a single library together
        with other library facilities not covered by this License,
        and distribute such a combined library, provided that the
        separate distribution of the work based on the Library and
        of the other library facilities is otherwise permitted,
        and provided that you do these two things:</para>

        <blockquote>
            <para>a) Accompany the combined library with a copy of
            the same work based on the Library, uncombined with any
            other library facilities.  This must be distributed under
            the terms of the Sections above.</para>

            <para>b) Give prominent notice with the combined library of
            the fact that part of it is a work based on the Library,
            and explaining where to find the accompanying uncombined
            form of the same work.</para>
        </blockquote>

        <para>8. You may not copy, modify, sublicense, link with,
        or distribute the Library except as expressly provided
        under this License.  Any attempt otherwise to copy, modify,
        sublicense, link with, or distribute the Library is void, and
        will automatically terminate your rights under this License.
        However, parties who have received copies, or rights, from
        you under this License will not have their licenses terminated
        so long as such parties remain in full compliance.</para>

        <para>9. You are not required to accept this License,
        since you have not signed it.  However, nothing else grants
        you permission to modify or distribute the Library or its
        derivative works.  These actions are prohibited by law if
        you do not accept this License.  Therefore, by modifying or
        distributing the Library (or any work based on the Library),
        you indicate your acceptance of this License to do so, and
        all its terms and conditions for copying, distributing or
        modifying the Library or works based on it.</para>

        <para>10. Each time you redistribute the Library (or any work
        based on the Library), the recipient automatically receives
        a license from the original licensor to copy, distribute,
        link with or modify the Library subject to these terms and
        conditions.  You may not impose any further restrictions
        on the recipients' exercise of the rights granted herein.
        You are not responsible for enforcing compliance by third
        parties with this License.</para>

        <para>11. If, as a consequence of a court judgment or
        allegation of patent infringement or for any other reason
        (not limited to patent issues), conditions are imposed
        on you (whether by court order, agreement or otherwise)
        that contradict the conditions of this License, they do not
        excuse you from the conditions of this License.  If you cannot
        distribute so as to satisfy simultaneously your obligations
        under this License and any other pertinent obligations, then
        as a consequence you may not distribute the Library at all.
        For example, if a patent license would not permit royalty-free
        redistribution of the Library by all those who receive copies
        directly or indirectly through you, then the only way you
        could satisfy both it and this License would be to refrain
        entirely from distribution of the Library.</para>

        <para>If any portion of this section is held invalid or
        unenforceable under any particular circumstance, the balance
        of the section is intended to apply, and the section as a
        whole is intended to apply in other circumstances.</para>

        <para>It is not the purpose of this section to induce you
        to infringe any patents or other property right claims or
        to contest validity of any such claims; this section has the
        sole purpose of protecting the integrity of the free software
        distribution system which is implemented by public license
        practices.  Many people have made generous contributions to
        the wide range of software distributed through that system
        in reliance on consistent application of that system; it is
        up to the author/donor to decide if he or she is willing to
        distribute software through any other system and a licensee
        cannot impose that choice.</para>

        <para>This section is intended to make thoroughly clear
        what is believed to be a consequence of the rest of this
        License.</para>

        <para>12. If the distribution and/or use of the Library
        is restricted in certain countries either by patents or by
        copyrighted interfaces, the original copyright holder who
        places the Library under this License may add an explicit
        geographical distribution limitation excluding those countries,
        so that distribution is permitted only in or among countries
        not thus excluded.  In such case, this License incorporates the
        limitation as if written in the body of this License.</para>

        <para>13. The Free Software Foundation may publish revised
        and/or new versions of the Lesser General Public License from
        time to time.  Such new versions will be similar in spirit
        to the present version, but may differ in detail to address
        new problems or concerns.</para>

        <para>Each version is given a distinguishing version number.
        If the Library specifies a version number of this License which
        applies to it and "any later version", you have the option of
        following the terms and conditions either of that version or of
        any later version published by the Free Software Foundation.
        If the Library does not specify a license version number,
        you may choose any version ever published by the Free Software
        Foundation.</para>

        <para>14. If you wish to incorporate parts of the Library
        into other free programs whose distribution conditions are
        incompatible with these, write to the author to ask for
        permission.  For software which is copyrighted by the Free
        Software Foundation, write to the Free Software Foundation;
        we sometimes make exceptions for this.  Our decision will be
        guided by the two goals of preserving the free status of all
        derivatives of our free software and of promoting the sharing
        and reuse of software generally.</para>

        <para>NO WARRANTY</para>

        <para>15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
        THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED
        BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING
        THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
        "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR
        IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
        LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE,
        YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
        CORRECTION.</para>

        <para>16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW
        OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY
        OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS
        PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
        GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
        OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT
        NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE
        OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
        THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
        HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
        SUCH DAMAGES.</para>

        <para>END OF TERMS AND CONDITIONS</para>
    </sect3>


    <sect3>
        <title>How to Apply These Terms to Your New
        Libraries</title>

        <para>If you develop a new library, and you want it to be of
        the greatest possible use to the public, we recommend making
        it free software that everyone can redistribute and change.
        You can do so by permitting redistribution under these terms
        (or, alternatively, under the terms of the ordinary General
        Public License).</para>

        <para>To apply these terms, attach the following notices to
        the library.  It is safest to attach them to the start of
        each source file to most effectively convey the exclusion of
        warranty; and each file should have at least the "copyright"
        line and a pointer to where the full notice is found.</para>

        <blockquote>
            <para>&lt;one line to give the library's name and a brief
            idea of what it does.&gt;</para>

            <para>Copyright &copy; &lt;year&gt; &lt;name of
            author&gt;</para>

            <para>This library is free software; you can redistribute
            it and/or modify it under the terms of the GNU Lesser
            General Public License as published by the Free Software
            Foundation; either version 2.1 of the License, or (at
            your option) any later version.</para>

            <para>This library is distributed in the hope that it
            will be useful, but WITHOUT ANY WARRANTY; without even
            the implied warranty of MERCHANTABILITY or FITNESS FOR
            A PARTICULAR PURPOSE.  See the GNU Lesser General Public
            License for more details.</para>

            <para>You should have received a copy of the GNU Lesser
            General Public License along with this library; if not,
            write to the Free Software Foundation, Inc., 59 Temple
            Place, Suite 330, Boston, MA 02111-1307 USA</para>
        </blockquote>

        <para>Also add information on how to contact you by electronic
        and paper mail.</para>

        <para>You should also get your employer (if you work as
        a programmer) or your school, if any, to sign a "copyright
        disclaimer" for the library, if necessary.  Here is a sample;
        alter the names:</para>

        <blockquote>
            <para>Yoyodyne, Inc., hereby disclaims all copyright
            interest in the library `Frob' (a library for tweaking
            knobs) written by James Random Hacker.</para>

            <para>&lt;signature of Ty Coon&gt;, 1 April 1990</para>

            <para>Ty Coon, President of Vice</para>
        </blockquote>

        <para>That's all there is to it!</para>
    </sect3>
</sect2>


<?hard-pagebreak?>
<sect2>
    <title>MySQL++ User Manual License</title>

    <sect3>
        <title>I. COPYRIGHT</title>

        <para>The copyright to the MySQL++ User Manual is owned by
        its authors.</para>
    </sect3>

    <sect3>
        <title>II. LICENSE</title>

        <para>The MySQL++ User Manual may be reproduced and
        distributed in whole or in part, in any medium physical or
        electronic, provided that this license notice is displayed
        in the reproduction. Commercial redistribution is permitted
        and encouraged. Thirty days advance notice via email to the
        authors of redistribution is appreciated, to give the authors
        time to provide updated documents.</para>

        <sect4>
            <title>A. REQUIREMENTS OF MODIFIED WORKS</title>

            <para>All modified documents, including translations,
            anthologies, and partial documents, must meet the following
            requirements:</para>

            <orderedlist numeration="arabic">
                <listitem><para>The modified version must be labeled
                as such.</para></listitem>

                <listitem><para>The person making the modifications
                must be identified.</para></listitem>

                <listitem><para>Acknowledgement of the original author
                must be retained.</para></listitem>

                <listitem><para>The location of the original unmodified
                document be identified.</para></listitem>

                <listitem><para>The original authors' names may
                not be used to assert or imply endorsement of the
                resulting document without the original authors'
                permission.</para></listitem>
            </orderedlist>

            <para>In addition it is requested that:</para>

            <orderedlist numeration="arabic">
                <listitem><para>The modifications (including deletions)
                be noted.</para></listitem>

                <listitem><para>The authors be notified by email of the
                modification in advance of redistribution, if an email
                address is provided in the document.</para></listitem>
            </orderedlist>

            <para>Mere aggregation of the MySQL++ User Manual with
            other documents or programs on the same media shall not
            cause this license to apply to those other works.</para>

            <para>All translations, derivative documents, or modified
            documents that incorporate the MySQL++ User Manual may
            not have more restrictive license terms than these,
            except that you may require distributors to make the
            resulting document available in source format.</para>
        </sect4>
    </sect3>
</sect2>
</sect1>
</article>

Added examples/Makefile.am.
























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
noinst_PROGRAMS = resetdb simple1 custom1 custom2 custom3 custom4 complic1 fieldinf1

noinst_HEADERS = util.hh

LDADD = $(top_builddir)/sqlplusint/libsqlplus.la @MYSQL_LIBS@
INCLUDES = -I$(top_srcdir)/sqlplusint @MYSQL_CFLAGS@

simple1_SOURCES = simple1.cc

# sinisa_ex_SOURCES = sinisa_ex.cc

resetdb_SOURCES = resetdb.cc util.cc

custom1_SOURCES = custom1.cc

custom2_SOURCES = custom2.cc util.cc

custom3_SOURCES = custom3.cc util.cc

custom4_SOURCES = custom4.cc

complic1_SOURCES = complic1.cc

fieldinf1_SOURCES = fieldinf1.cc
Deleted examples/cgi_jpeg.cpp.
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













































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 cgi_jpeg.cpp - Example code showing how to fetch JPEG data from a BLOB
 	column and send it back to a browser that requested it by ID.
	
	Use load_jpeg.cpp to load JPEG files into the database we query.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>
#include <custom.h>

using namespace std;
using namespace mysqlpp;

#define IMG_DATABASE	"mysql_cpp_data"
#define IMG_HOST		"localhost"
#define IMG_USER		"root"
#define IMG_PASSWORD 	"nunyabinness"

sql_create_2(images,
	1, 2,
	mysqlpp::sql_int_unsigned, id,
	mysqlpp::sql_blob, data)

int
main()
{
	unsigned int img_id = 0;
	char* cgi_query = getenv("QUERY_STRING");
	if (cgi_query) {
		if ((strlen(cgi_query) < 4) || memcmp(cgi_query, "id=", 3)) {
			cout << "Content-type: text/plain" << endl << endl;
			cout << "ERROR: Bad query string" << endl;
			return 1;
		}
		else {
			img_id = atoi(cgi_query + 3);
		}
	}
	else {
		cerr << "Put this program into a web server's cgi-bin "
				"directory, then" << endl;
		cerr << "invoke it with a URL like this:" << endl;
		cerr << endl;
		cerr << "    http://server.name.com/cgi-bin/cgi_jpeg?id=2" <<
				endl;
		cerr << endl;
		cerr << "This will retrieve the image with ID 2." << endl;
		cerr << endl;
		cerr << "You will probably have to change some of the #defines "
				"at the top of" << endl;
		cerr << "examples/cgi_jpeg.cpp to allow the lookup to work." <<
				endl;
		return 1;
	}

	Connection con(use_exceptions);
	try {
		con.connect(IMG_DATABASE, IMG_HOST, IMG_USER, IMG_PASSWORD);
		Query query = con.query();
		query << "SELECT * FROM images WHERE id = " << img_id;
		ResUse res = query.use();
		if (res) {
			images img = res.fetch_row();
			cout << "Content-type: image/jpeg" << endl;
			cout << "Content-length: " << img.data.length() << "\n\n";
			cout << img.data;
		}
		else {
			cout << "Content-type: text/plain" << endl << endl;
			cout << "ERROR: No such image with ID " << img_id << endl;
		}
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cout << "Content-type: text/plain" << endl << endl;
		cout << "QUERY ERROR: " << er.what() << endl;
		return 1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cout << "Content-type: text/plain" << endl << endl;
		cout << "GENERAL ERROR: " << er.what() << endl;
		return 1;
	}

	return 0;
}
Added examples/complic1.cc.




































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <iomanip>
#include <sqlplus.hh>

int main() {
  try { // its in one big try block

    Connection con(use_exceptions);
    con.connect("mysql_cpp_data");
    // Here I broke making the connection into two calls.
    // The first one creates the Connection object with the 
    // use exceptions option turned on and the second one
    // makes the connection
    
    Query query = con.query();
    
    query << "select * from stock";
    Result res = query.store();
    
    cout << "Query: " << query.preview() << endl;
    cout << "Records Found: " << res.size() << endl << endl;
    
    Row row;
    cout.setf(ios::left);
    cout << setw(17) << "Item" 
       << setw(4)  << "Num"
       << setw(7)  << "Weight"
       << setw(7)  << "Price" 
       << "Date" << endl
       << endl;
  
    Result::iterator i;
    
    cout.precision(3);
    for (i = res.begin(); i != res.end(); i++) {
      row = *i;
      cout << setw(17) << row["item"] << setw(4) << row[1] 
	   << setw(7)  << (double)row[2]
	// This is converting the row to a double so that we
	// can set the precision of it.  
	// ColData has the nice feature that it will convert to
	// any of the basic c++ types.  if there is a problem
	// in the conversion it will throw an exception (which I 
	// cache below).  To test it try changing the 2 in row[2]
	// to row[0]
	   << setw(7) << (double)row[3];
      Date date = row["sdate"]; 
      // The ColData is implicitly converted to a date here.
      cout.setf(ios::right);
      cout.fill('0');
      cout << setw(2) << date.month << "-" << setw(2) << date.day << endl;
      cout.fill(' ');
      cout.unsetf(ios::right);
    }
    return 0;
  } catch (BadQuery er) { // handle any connection or
                          // query errors that may come up
    cerr << "Error: " << er.error << endl;
    return -1;
  } catch (BadConversion er) { // handle bad conversions
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" 
	 << er.type_name << "\"." << endl;
    return -1;
  }
}


Added examples/custom1.cc.














































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <iomanip>
#include <vector>
#include <sqlplus.hh>
#include <custom.hh>

sql_create_5 (stock,		// struct name, 
	      1, 5,		// I'll explain these latter
	      string, item,	// type, id
	      int, num,
	      double, weight,
	      double, price,
	      Date, sdate)

// this is calling a very complex macro which will create a custom
// struct "stock" which has the variables:
//   string item
//    int num
//    ...
//    Date sdate
// defined as well methods to help populate the class from a mysql row
// among other things that I'll get too in a latter example

int main () {
  try {				// its in one big try block
    Connection con (use_exceptions);
    con.connect ("mysql_cpp_data");
    Query query = con.query ();
    query << "select * from stock";

    vector < stock > res;
    query.storein (res);
    // this is storing the results into a vector of the custom struct
    // "stock" which was created my the macro above.

    cout.setf (ios::left);
    cout << setw (17) << "Item"
	 << setw (4) << "Num"
	 << setw (7) << "Weight"
	 << setw (7) << "Price"
	 << "Date" << endl
	 << endl;

    // Now we we iterate through the vector using an iterator and
    // produce output similar to that using Row
    // Notice how we call the actual variables in i and not an index
    // offset.  This is because the macro at the begging of the file
    // set up an *actual* struct of type stock which contains the 
    // variables item, num, weight, price, and data.

    cout.precision(3);
    vector <stock>::iterator i;
    for (i = res.begin (); i != res.end (); i++) {
      cout << setw (17) << i->item.c_str ()
	// unfortunally the gnu string class does not respond to format
	// modifers so I have to convert it to a conat char *.
	   << setw (4) << i->num
	   << setw (7) << i->weight
	   << setw (7) << i->price
	   << i->sdate
	   << endl;
    }
    return 0;
    
  } catch (BadQuery er){ // handle any connection 
                         // or query errors that may come up
    cerr << "Error: " << er.error << endl;
    return -1;

  } catch (BadConversion er) {
    // we still need to cache bad conversions incase something goes 
    // wrong when the data is converted into stock
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \""
	 << er.type_name << "\"." << endl;
    return -1;
  }
}
Deleted examples/custom1.cpp.
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



















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 custom1.cpp - Example that produces the same results as simple1, but it
 	uses a Specialized SQL Structure to store the results instead of a
	MySQL++ Result object.
 
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stock.h"
#include "util.h"

#include <iostream>
#include <vector>

using namespace std;

int
main(int argc, char *argv[])
{
	// Wrap all MySQL++ interactions in one big try block, so any
	// errors are handled gracefully.
	try {						
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Retrieve the entire contents of the stock table, and store
		// the data in a vector of 'stock' SSQLS structures.
		mysqlpp::Query query = con.query();
		query << "select * from stock";
		vector<stock> res;
		query.storein(res);

		// Display the result set
		print_stock_header(res.size());
		vector<stock>::iterator it;
		for (it = res.begin(); it != res.end(); ++it) {
			print_stock_row(it->item, it->num, it->weight, it->price,
					it->sdate);
		}
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions; e.g. type mismatch populating 'stock'
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Added examples/custom2.cc.

















































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <vector>
#include <sqlplus.hh>
#include <custom.hh>
#include "util.hh"
// util.hh/cc contains the print_stock_table function

sql_create_5(stock, 1, 5, string, item, int, num, 
	     double, weight, double, price, Date, sdate)

int main() {
  try { // its in one big try block

    Connection con(use_exceptions);
    con.connect("mysql_cpp_data");
    Query query = con.query();

    stock row;
    // create an empty stock object
    
    /*    row.item = "Hot Dogs";
    row.num = 100;
    row.weight = 1.5;
    row.price = 1.75;
    row.sdate = "1998-09-25"; */
    row.set("Hot Dogs", 100, 1.5, 1.75, "1998-09-25");
    // populate stock

    query.insert(row);
    // form the query to insert the row
    // the table name is the name of the struct by default
    cout << "Query : " << query.preview() << endl;
    // show the query about to be executed
    query.execute();
    // execute a query that does not return a result set

    print_stock_table(query);
    // now print the new table;
    
  } catch (BadQuery er) {
    cerr << "Error: " << er.error << endl;
    return -1;
  } catch (BadConversion er) { 
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" 
	 << er.type_name << "\"." << endl;
    return -1;
  }
}
Deleted examples/custom2.cpp.
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





















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 custom2.cpp - Example showing how to insert a row using the Specialized
 	SQL Structures feature of MySQL++.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stock.h"
#include "util.h"

#include <iostream>

using namespace std;

int
main(int argc, char *argv[])
{
	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Create and populate a stock object.  We could also have used
		// the set() member, which takes the same parameters as this
		// constructor.
		stock row("Hot Dogs", 100, 1.5, 1.75, "1998-09-25");

		// Form the query to insert the row into the stock table.
		mysqlpp::Query query = con.query();
		query.insert(row);

		// Show the query about to be executed.
		cout << "Query: " << query.preview() << endl;

		// Execute the query.  We use execute() because INSERT doesn't
		// return a result set.
		query.execute();

		// Print the new table.
		mysqlpp::Result res;
		get_stock_table(query, res);
		print_stock_rows(res);
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {	
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Added examples/custom3.cc.
























































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <vector>
#include <sqlplus.hh>
#include <custom.hh>
#include "util.hh"
// util.hh/cc contains the print_stock_table function

sql_create_5(stock, 1, 5, string, item, int, num, 
	     double, weight, double, price, Date, sdate)

int main() {
  try { // its in one big try block

    Connection con(use_exceptions);
    con.connect("mysql_cpp_data");
    Query query = con.query();

    query << "select * from stock where item = \"Hotdogs' Buns\" ";
    
    Result res = query.store();
    if (res.empty()) 
      throw BadQuery("Hotdogs' Buns not found in table, run reset-db");
    // here we are testing if the query was successful, if not throw a bad query
    stock row = res[0];
    // because there should only be one row in this query we don't
    // need to use a vector.  Just store the first row directly in
    // "row".  We can do this because one of the constructors for
    // stock takes a Row as an parameter.

    stock row2 = row;
    // Now we need to create a copy so that the replace query knows
    // what the original values are.

    row.item = "Hotdog Buns"; // now change item

    query.update(row2, row);
    // form the query to replace the row
    // the table name is the name of the struct by default
    cout << "Query : " << query.preview() << endl;
    // show the query about to be executed
    query.execute();
    // execute a query that does not return a result set

    print_stock_table(query);
    // now print the new table;
    
  } catch (BadQuery er) {
    cerr << "Error: " << er.error << endl;
    return -1;
  } catch (BadConversion er) { 
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" 
	 << er.type_name << "\"." << endl;
    return -1;
  }
}
Deleted examples/custom3.cpp.
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









































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 custom3.cpp - Example showing how to update an SQL row using the
	Specialized SQL Structures feature of MySQL++.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stock.h"
#include "util.h"

#include <iostream>

using namespace std;

int
main(int argc, char *argv[])
{
	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Build a query to retrieve the stock item that has Unicode
		// characters encoded in UTF-8 form.
		mysqlpp::Query query = con.query();
		query << "select * from stock where item = \"Nürnberger Brats\"";

		// Retrieve the row, throwing an exception if it fails.
		mysqlpp::Result res = query.store();
		if (res.empty()) {
			throw mysqlpp::BadQuery("UTF-8 bratwurst item not found in "
					"table, run resetdb");
		}

		// Because there should only be one row in the result set,
		// there's no point in storing the result in an STL container.
		// We can store the first row directly into a stock structure
		// because one of an SSQLS's constructors takes a Row object.
		stock row = res.at(0);

		// Create a copy so that the replace query knows what the
		// original values are.
		stock orig_row = row;

		// Change the stock object's item to use only 7-bit ASCII, and
		// to deliberately be wider than normal column widths printed
		// by print_stock_table().
		row.item = "Nuerenberger Bratwurst";

		// Form the query to replace the row in the stock table.
		query.update(orig_row, row);

		// Show the query about to be executed.
		cout << "Query: " << query.preview() << endl;

		// Run the query with execute(), since UPDATE doesn't return a
		// result set.
		query.execute();

		// Print the new table contents.
		get_stock_table(query, res);
		print_stock_rows(res);
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Added examples/custom4.cc.









































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <iomanip>
#include <vector>
#include <sqlplus.hh>
#include <custom.hh>

sql_create_5(stock, 
	     1, // This number is used to make a SSQLS less-than-comparable.
	        // If this number is n then if the first n elements are the 
	        // same the two SSQLS are the same.  
	        // In this case if two two stock's "item" are the same then
	        // the two stock are the same.
	     5, // this number should generally be the same as the number of
	        // elements in the list unless you have a good reason not to.

	     string,item,  int,num,  double,weight,  double,price,  Date,sdate)

int main() {
  try { // its in one big try block

    Connection con(use_exceptions);
    con.connect("mysql_cpp_data");
    Query query = con.query();

    query << "select * from stock";
    
    set<stock> res;
    query.storein(res);
    // here we are storing the elements in a set not a vector.

    cout.setf (ios::left);
    cout << setw (17) << "Item"
	 << setw (4) << "Num"
	 << setw (7) << "Weight"
	 << setw (7) << "Price"
	 << "Date" << endl
	 << endl;

    // Now we we iterate through the set.  Since it is a set the list will
    // naturally be in order.
    
    set<stock>::iterator i;
    cout.precision(3);
    for (i = res.begin (); i != res.end (); i++) {
      cout << setw (17) << i->item.c_str ()
	   << setw (4) << i->num
	   << setw (7) << i->weight
	   << setw (7) << i->price
	   << i->sdate
	   << endl;
    }

    i = res.find(stock("Hamburger Buns"));
    if (i != res.end())
      cout << "Hamburger Buns found.  Currently " << i->num << " in stock.\n";
    else
      cout << "Sorry no Hamburger Buns found in stock\n";

    // Now we are using the set's find method to find out how many
    // Hamburger Buns are in stock.

    return 0;

  } catch (BadQuery er) {
    cerr << "Error: " << er.error << endl;
    return -1;
  } catch (BadConversion er) { 
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" 
	 << er.type_name << "\"." << endl;
    return -1;
  }
}
Deleted examples/custom4.cpp.
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

































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 custom4.cpp - Example very similar to custom1.cpp, except that it
	stores its result set in an STL set container.  This demonstrates
	how one can manipulate MySQL++ result sets in a very natural C++
	style.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stock.h"
#include "util.h"

#include <iostream>

using namespace std;

int
main(int argc, char *argv[])
{
	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Retrieve all rows from the stock table and put them in an
		// STL set.  Notice that this works just as well as storing them
		// in a vector, which we did in custom1.cpp.  It works because
		// SSQLS objects are less-than comparable.
		mysqlpp::Query query = con.query();
		query << "select * from stock";
		set<stock> res;
		query.storein(res);

		// Display the result set.  Since it is an STL set and we set up
		// the SSQLS to compare based on the item column, the rows will
		// be sorted by item.
		print_stock_header(res.size());
		set<stock>::iterator it;
		cout.precision(3);
		for (it = res.begin(); it != res.end(); ++it) {
			print_stock_row(it->item.c_str(), it->num, it->weight,
					it->price, it->sdate);
		}

		// Use set's find method to look up a stock item by item name.
		// This also uses the SSQLS comparison setup.
		it = res.find(stock("Hotdog Buns"));
		if (it != res.end()) {
			cout << endl << "Currently " << it->num <<
					" hotdog buns in stock." << endl;
		}
		else {
			cout << endl << "Sorry, no hotdog buns in stock." << endl;
		}
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted examples/custom5.cpp.
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


















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 custom5.cpp - Example showing how to use the equal_list() member of
 	some SSQLS types to build SELECT queries with custom WHERE clauses.
 
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, (c) 2004, 2005 by Educational Technology Resources, Inc., and
 (c) 2005 by Chris Frey.  Others may also hold copyrights on code in
 this file.  See the CREDITS file in the top directory of the
 distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stock.h"
#include "util.h"

#include <iostream>
#include <vector>

using namespace std;

int
main(int argc, char *argv[])
{
	try {
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Get all the rows in the stock table.
		mysqlpp::Query query = con.query();
		query << "select * from stock";
		vector<stock> res;
		query.storein(res);

		if (res.size() > 0) {
			// Build a select query using the data from the first row
			// returned by our previous query.
			query.reset();
			query << "select * from stock where " <<
				res[0].equal_list(" and ", stock_weight, stock_price);

			// Display the finished query.
			cout << "Custom query:\n" << query.preview() << endl;
		}
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted examples/custom6.cpp.
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


























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 custom6.cpp - Same as custom1, except that it requests only a subset of
 	the stock table.  See also simple1, for another way to accomplish
	the same thing, without using SSQLS.
 
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>
#include <custom.h>

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

// To store a subset of a row, we define an SSQLS containing just the
// fields that we will store.  There are complications here that are
// covered in the user manual.
sql_create_1(stock_subset,
			 1, 0,
			 string, item)

int
main(int argc, char *argv[])
{
	try {						
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Retrieve a subset of the stock table, and store the data in
		// a vector of 'stock_subset' SSQLS structures.
		mysqlpp::Query query = con.query();
		query << "select item from stock";
		vector<stock_subset> res;
		query.storein(res);

		// Display the result set
		cout << "We have:" << endl;
		vector<stock_subset>::iterator it;
		for (it = res.begin(); it != res.end(); ++it) {
			cout << '\t' << it->item << endl;
		}
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions; e.g. type mismatch populating 'stock'
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted examples/dbinfo.cpp.
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
























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 dbinfo.cpp - Example showing how to request information about the
	database schema, such as table names, column types, etc.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

using namespace std;
using namespace mysqlpp;

vector<string> yy;

static ostream&
separator(ostream& os)
{
	os << endl << "---------------------------" << endl << endl;
	return os;
}

int
main(int argc, char* argv[])
{
	Connection con(use_exceptions);
	try {
		connect_to_db(argc, argv, con, "");

		// Show MySQL version
		cout << "MySQL version: " << con.client_info() << separator;
		Query query = con.query();

		// Show all the databases we can see
		query << "show databases";
		cout << "Query: " << query.preview() << endl;

		Result res = query.store();
		cout << "Databases found: " << res.size();

		Row row;
		cout.setf(ios::left);
		Result::iterator i;
		for (i = res.begin(); i != res.end(); ++i) {
			row = *i;
			cout << endl << '\t' << setw(17) << row.at(0);
		}
		cout << separator;
		
		// Show the tables in the mysql database
		con.select_db("mysql");

		query.reset();
		query << "show tables";
		cout << "Query: " << query.preview() << endl;

		res = query.store();
		cout << "Tables found: " << res.size();

		cout.setf(ios::left);
		for (i = res.begin(); i != res.end(); ++i) {
			row = *i;
			string xx(row.at(0));
			cout << endl << '\t' << setw(17) << row.at(0);
			yy.push_back(xx);
		}
		cout << separator;

		// Show information about each of the tables we found
		for (unsigned int j = 0; j < yy.size(); ++j) {
			query.reset();
			query << "describe " << yy[j] << "";
			cout << "Query: " << query.preview() << endl;
			res = query.store();
			unsigned int columns = res.num_fields(), counter;
			vector<int> widths;
			for (counter = 0; counter < columns; counter++) {
				string s = res.names(counter);
				if (s.compare("field") == 0) {
					widths.push_back(22);
				}
				else if (s.compare("type") == 0) {
					widths.push_back(20);
				}
				else if (s.compare("null") == 0) {
					widths.push_back(4);
				}
				else if (s.compare("key") == 0) {
					widths.push_back(3);
				}
				else if (s.compare("extra") == 0) {
					widths.push_back(0);
				}
				else {
					widths.push_back(15);
				}

				if (widths[counter]) {
					cout << '|' << setw(widths[counter]) <<
							res.names(counter) << '|';
				}
			}
			cout << endl;

			for (i = res.begin(); i != res.end(); ++i) {
				row = *i;
				for (counter = 0; counter < columns; counter++) {
					if (widths[counter]) {
						cout << ' ' << setw(widths[counter]) <<
								row.at(counter) << ' ';
					}
				}
				cout << endl;
			}

			cout << separator;
		}

		// Show the user table contents
		query.reset();
	 	query << "select * from user";
		cout << "Query: " << query.preview() << endl << endl;

		res = query.store();
		int columns = res.num_fields();
		cout << "fields = " << res.num_fields() << ", rows = " <<
				res.size() << endl;
		volatile MYSQL_RES* ress = res.raw_result();
		if (!ress)
			return -1;
		for (i = res.begin(); i != res.end(); ++i) {
			row = *i;
			for (int counter = 0; counter < columns; counter++) {
				cout << row.at(counter) << "  ";
			}
			cout << endl;
		}
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Added examples/fieldinf1.cc.


































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <iomanip>
#include <sqlplus.hh>

int main() {
  try { // its in one big try block

    Connection con(use_exceptions);
    con.connect("mysql_cpp_data");
    Query query = con.query();
    query << "select * from stock";
    Result res = query.store();
    
    cout << "Query: " << query.preview() << endl;
    cout << "Records Found: " << res.size() << endl << endl;

    cout << "Query Info:\n";
    cout.setf(ios::left);

    for (unsigned int i = 0; i < res.names().size(); i++) {
      cout << setw(2)  << i
	   << setw(15) << res.names(i).c_str()
	// this is the name of the field
	   << setw(15) << res.types(i).sql_name()
	// this is the SQL identifier name
	// Result::types(unsigned int) returns a mysql_type_info which in many
	// ways is like type_info except that it has additional sql type
	// information in it. (with one of the methods being sql_name())
	   << setw(20) << res.types(i).name()
	// this is the C++ identifier name which most closely resembles
	// the sql name (its is implementation defined and often not very readable)
	   << endl;
    }

    cout << endl;
    
    if (res.types(0) == typeid(string))
      cout << "Field 'item' is of an sql type which most closely resembles a\n"
	   << "the c++ string type\n";
    // this is demonstrating how a mysql_type_info can be compared with a c++
    // type_info.

    if (res.types(1) == typeid(short int))
      cout << "Field 'num' is of an sql type which most closely resembles a\n"
	   << "the c++ short int type\n";
    else if (res.types(1).base_type() == typeid(short int))
      cout << "Field 'num' base type is of an sql type which most closely \n"
	   << "resembles a the c++ short int type\n";
    // However you have to be careful as if it can be null the actual type is 
    // Null<TYPE> not TYPE.  So you should always use the base_type method
    // to get at the underlying type.  If the type is not null than this base
    // type would be the same as its type.
    
    return 0;
  } catch (BadQuery er) {
    cerr << "Error: " << er.error << endl;
    return -1;
  } catch (BadConversion er) { // handle bad conversions
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" 
	 << er.type_name << "\"." << endl;
    return -1;
  }
}


Deleted examples/fieldinf1.cpp.
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



















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 fieldinf1.cpp - Example showing how to request information about the
 	fields in a table, such as their SQL and C++-equivalent types, as
	MySQL++ sees it.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;
using namespace mysqlpp;

int
main(int argc, char *argv[])
{
	try {
		Connection con(use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		Query query = con.query();
		query << "select * from stock";
		cout << "Query: " << query.preview() << endl;

		Result res = query.store();
		cout << "Records Found: " << res.size() << endl << endl;

		cout << "Query Info:\n";
		cout.setf(ios::left);

		for (unsigned int i = 0; i < res.names().size(); i++) {
			cout << setw(2) << i
					// this is the name of the field
					<< setw(15) << res.names(i).c_str()
					// this is the SQL identifier name
					// Result::types(unsigned int) returns a mysql_type_info which in many
					// ways is like type_info except that it has additional sql type
					// information in it. (with one of the methods being sql_name())
					<< setw(15) << res.types(i).sql_name()
					// this is the C++ identifier name which most closely resembles
					// the sql name (its is implementation defined and often not very readable)
					<< setw(20) << res.types(i).name()
					<< endl;
		}

		cout << endl;

		if (res.types(0) == typeid(string)) {
			// this is demonstrating how a mysql_type_info can be 
			// compared with a C++ type_info.
			cout << "Field 'item' is of an SQL type which most "
					"closely resembles\nthe C++ string type\n";
		}

		if (res.types(1) == typeid(longlong)) {
			cout << "Field 'num' is of an SQL type which most "
					"closely resembles\nC++ long long int type\n";
		}
		else if (res.types(1).base_type() == typeid(longlong)) {
			// you have to be careful as if it can be null the actual
			// type is Null<TYPE> not TYPE.  So you should always use
			// the base_type method to get at the underlying type.
			// If the type is not null than this base type would be
			// the same as its type.
			cout << "Field 'num' base type is of an SQL type which "
					"most closely\nresembles the C++ long long int type\n";
		}
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted examples/for_each.cpp.
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








































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 for_each.cpp - Demonstrates Query::for_each(), showing how to perform
	an arbitrary action on each row in a result set.

 Copyright (c) 2005-2007 by Joel Fielder and Educational Technology
 Resources, Inc.  Others may also hold copyrights on code in this file.
 See the CREDITS file in the top directory of the distribution for
 details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"
#include "stock.h"

#include <mysql++.h>

#include <iostream>

#include <math.h>


// Define a functor to collect statistics about the stock table
class gather_stock_stats
{
public:
	gather_stock_stats() :
	items_(0),
	weight_(0),
	cost_(0)
	{
	}

	void operator()(const stock& s)
	{
		items_  += s.num;
		weight_ += (s.num * s.weight);
		cost_   += (s.num * s.price);
	}
	
private:
	mysqlpp::sql_bigint items_;
	mysqlpp::sql_double weight_, cost_;

	friend std::ostream& operator<<(std::ostream& os,
			const gather_stock_stats& ss);
};


// Dump the contents of gather_stock_stats to a stream in human-readable
// form.
std::ostream&
operator<<(std::ostream& os, const gather_stock_stats& ss)
{
	os << ss.items_ << " items " <<
			"weighing " << ss.weight_ << " stone and " <<
			"costing " << ss.cost_ << " cowrie shells";
	return os;
}


int
main(int argc, char *argv[])
{
	try {
		// Connect to the sample database
		mysqlpp::Connection con;
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Gather and display the stats for the entire stock table
		mysqlpp::Query query = con.query();
		std::cout << "There are " << query.for_each(stock(),
				gather_stock_stats()) << '.' << std::endl;
	}
	catch (const mysqlpp::BadQuery& e) {
		// Something went wrong with the SQL query.
		std::cerr << "Query failed: " << e.what() << std::endl;
		return 1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		std::cerr << "Error: " << er.what() << std::endl;
		return 1;
	}

	return 0;
}
Deleted examples/load_jpeg.cpp.
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

























































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 load_jpeg.cpp - Example showing how to insert BLOB data into the
	database from a file.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <fstream>

using namespace std;
using namespace mysqlpp;

static bool
is_jpeg(const unsigned char* img_data)
{
	return (img_data[0] == 0xFF) && (img_data[1] == 0xD8) &&
			((memcmp(img_data + 6, "JFIF", 4) == 0) ||
			 (memcmp(img_data + 6, "Exif", 4) == 0));
}


int
main(int argc, char *argv[])
{
	// Assume that the last command line argument is a file.  Try to
	// read that file's data into img_data, and check it to see if it
	// appears to be a JPEG file.  Bail otherwise.
	string img_data;
	if ((argc > 1) && (argv[1][0] != '-')) {
		ifstream img_file(argv[argc - 1], ios::ate);
		if (img_file) {
			size_t img_size = img_file.tellg();
			if (img_size > 10) {
				img_file.seekg(0, ios::beg);
				char* img_buffer = new char[img_size];
				img_file.read(img_buffer, img_size);
				if (is_jpeg((unsigned char*)img_buffer)) {
					img_data.assign(img_buffer, img_size);
				}
				else {
					cerr << "File does not appear to be a JPEG!" << endl;
				}
				delete[] img_buffer;
			}
			else {
				cerr << "File is too short to be a JPEG!" << endl;
			}
		}
	}
	if (img_data.empty()) {
		print_usage(argv[0], "[jpeg_file]");
		return 1;
	}
	--argc;		// pop filename argument off end of list

	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Insert image data into the BLOB column in the images table.
		// We're inserting it as an std::string instead of using the raw
		// data buffer allocated above because we don't want the data
		// treated as a C string, which would truncate the data at the
		// first null character.
		Query query = con.query();
		query << "INSERT INTO images (data) VALUES(\"" <<
				mysqlpp::escape << img_data << "\")";
		ResNSel res = query.execute();

		// If we get here, insertion succeeded
		cout << "Inserted \"" << argv[argc] <<
				"\" into images table, " << img_data.size() <<
				" bytes, ID " << res.insert_id << endl;
	}
	catch (const BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted examples/logo.jpg.

cannot compute difference between binary files

Deleted examples/multiquery.cpp.
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


























































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 multiquery.cpp - Example showing how to iterate over result sets upon
    execution of a query that returns more than one result set.  You can
	get multiple result sets when executing multiple separate SQL
	statments in a single query, or when dealing with the results of
	calling a stored procedure.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, (c) 2004, 2005 by Educational Technology Resources, Inc.,
 and (c) 2005 by Arnon Jalon.  Others may also hold copyrights on
 code in this file.  See the CREDITS file in the top directory of
 the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;
using namespace mysqlpp;


typedef vector<int> IntVectorType;


static void
print_header(IntVectorType& widths, Result& res)
{
	cout << "  |" << setfill(' ');
	for (size_t i = 0; i < res.names().size(); i++) {
		cout << " " << setw(widths.at(i)) << res.names(i) << " |";
	}
	cout << endl;
}


static void
print_row(IntVectorType& widths, Row& row)
{
	cout << "  |" << setfill(' ');
	for (size_t i = 0; i < row.size(); i++) {
		cout << " " << setw(widths.at(i)) << row.raw_data(i) << " |";
	}
	cout << endl;
}


static void
print_row_separator(IntVectorType& widths)
{
	cout << "  +" << setfill('-');
	for (size_t i = 0; i < widths.size(); i++) {
		cout << "-" << setw(widths.at(i)) << '-' << "-+";
	}
	cout << endl;
}


static void
print_result(Result& res, int index)
{
	// Show how many rows are in result, if any
	int num_results = res.size();
	if (res && (num_results > 0)) {
		cout << "Result set " << index << " has " << num_results <<
				" row" << (num_results == 1 ? "" : "s") << ':' << endl;
	}
	else {
		cout << "Result set " << index << " is empty." << endl;
		return;
	}

	// Figure out the widths of the result set's columns
	IntVectorType widths;
	int size = res.columns();
	for (int i = 0; i < size; i++) {
		mysql_type_info mti(res.fields(i));
		widths.push_back((res.names(i).size() > mti.max_length()) ?
				res.names(i).size() : mti.max_length());
	}

	// Print result set header
	print_row_separator(widths);
	print_header(widths, res);
	print_row_separator(widths);

	// Display the result set contents
	for (int i = 0; i < num_results; ++i) {
		Row row = res.fetch_row();
		print_row(widths, row);
	}

	// Print result set footer
	print_row_separator(widths);
}


static void
print_multiple_results(Query& query)
{
	try {
		// Execute query and print all result sets
		Result res = query.store();
		print_result(res, 0);
		for (int i = 1; query.more_results(); ++i) {
			res = query.store_next();
			print_result(res, i);
		}
	}
	catch (Exception& err) {
		// Something bad happened....
		cerr << "Multi-query failure: " << err.what() << endl;
		exit(1);
	}
}


int
main(int argc, char *argv[])
{
	Connection con;
	try {
		// Enable multi-queries.  Notice that we can set connection
		// options before the connection is established, which the
		// underlying MySQL C API does not allow.  In this particular
		// case, this is not a mere nicety: the multi-query option has
		// a side effect of setting one of the flags used when 
		// establishing the database server connection.  We could set it
		// directly, but then we couldn't use connect_to_db().
		con.set_option(Connection::opt_multi_statements, true);

		// Connect to database
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}
	}
	catch (const BadOption& err) {
		if (err.what_option() == Connection::opt_multi_statements) {
			cerr << "This example only works when MySQL++ is built "
					"against MySQL C API" << endl;
			cerr << "version 4.1.01 or later." << endl;
		}
		else {
			cerr << "Unexpected option failure: " << err.what() << endl;
		}
		return 1;
	}
	catch (const ConnectionFailed& err) {
		cerr << "Failed to connect to database server: " <<
				err.what() << endl;
		return 1;
	}
	catch (const Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return 1;
	}

	// Set up query with multiple queries.
	Query query = con.query();
	query << "DROP TABLE IF EXISTS test_table;" << endl <<
			"CREATE TABLE test_table(id INT);" << endl <<
			"INSERT INTO test_table VALUES(10);" << endl <<
			"UPDATE test_table SET id=20 WHERE id=10;" << endl <<
			"SELECT * FROM test_table;" << endl <<
			"DROP TABLE test_table" << endl;
	cout << "Multi-query: " << endl << query.preview() << endl;

	// Execute statement and display all result sets.
	print_multiple_results(query);

#if MYSQL_VERSION_ID >= 50000
	// If it's MySQL v5.0 or higher, also test stored procedures, which
	// return their results the same way multi-queries do.
	query.reset();
	query << "DROP PROCEDURE IF EXISTS get_stock;" << endl <<
			"CREATE PROCEDURE get_stock" << endl <<
			"( i_item varchar(20) )" << endl <<
			"BEGIN" << endl <<
			"SET i_item = concat('%', i_item, '%');" << endl <<
			"SELECT * FROM stock WHERE lower(item) like lower(i_item);" << endl <<
			"END" << endl <<
			";";
	cout << "Stored procedure query: " << endl << query.preview() << endl;

	// Create the stored procedure.
	print_multiple_results(query);

	// Call the stored procedure and display its results.
	query.reset();
	query << "CALL get_stock('relish')";
	cout << "Query: " << query.preview() << endl;
	print_multiple_results(query);
#endif

	return 0;
}
Added examples/resetdb.cc.















































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include <iostream>
#include <sqlplus.hh>

int main (int argc, char *argv[]) {
  Connection connection(use_exceptions);
  try { // the entire main block is one big try block;

    if (argc == 1) connection.connect("");
    else if (argc == 2) connection.connect("",argv[1]);
    else if (argc == 3) connection.connect("",argv[1],argv[2]);
    else if (argc <= 4) connection.connect("",argv[1],argv[2],argv[3]);
    // create a new object and connect based on any (if any) arguments
    // passed to main();
    
    try {
      connection.select_db("mysql_cpp_data");
    } catch (BadQuery er) {
      // if it couldn't connect to the database assume that it doesn't exist
      // and try created it.  If that does not work exit with an error.
      connection.create_db("mysql_cpp_data");
      connection.select_db("mysql_cpp_data");
    }
    
    Query query = connection.query();  // create a new query object
    
    try { // ignore any errors here
          // I hope to make this simpler soon
      query.execute("drop table stock");
    } catch (BadQuery er) {}
    
    query << "create table stock  (item char(20) not null, num smallint,"
	  << "weight double, price double, sdate date)";
    query.execute(RESET_QUERY);
    // send the query to create the table and execute it.  The
    // RESET_QUERY tells the query object to reset it self after
    // execution
    
    query << "insert into %5:table values (%0q, %1q, %2, %3, %4q)";
    query.parse();
    // set up the template query I will use to insert the data.  The
    // parse method call is important as it is what lets the query
    // know that this is a template and not a literal string
    
    query.def["table"] = "stock";
    // This is setting the parameter named table to stock.
    
    query.execute ("Hamburger Buns", 56, 1.25, 1.1, "1998-04-26");
    query.execute ("Hotdogs' Buns"   ,65, 1.1 , 1.1, "1998-04-23");
    query.execute ("Dinner Roles"  , 75,  .95, .97, "1998-05-25");
    query.execute ("White Bread"   , 87, 1.5, 1.75, "1998-09-04");
    // The last parameter "table" is not specified here.  Thus
    // the default value for "table" is used which is "stock".

  } catch (BadQuery er) { // handle any errors that may come up
    cerr << "Error: " << er.error << endl;
    return -1;
  }
}




















Deleted examples/resetdb.cpp.
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



















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 resetdb.cpp - (Re)initializes the example database, mysql_cpp_data.
 	You must run this at least once before running most of the other
	examples, and it is helpful sometimes to run it again, as some of
	the examples modify the table in this database.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>

using namespace std;

// Convert a packed version number in the format used within MySQL++
// to a printable string.
static string
version_str(int packed)
{
	char buf[9];
	snprintf(buf, sizeof(buf), "%d.%d.%d",
			(packed & 0xFF0000) >> 16,
			(packed & 0x00FF00) >> 8,
			(packed & 0x0000FF));
	return buf;
}


int
main(int argc, char *argv[])
{
	// Ensure that we're not mixing library and header file versions.
	// This is really easy to do if you have MySQL++ on your system and
	// are trying to build a new version, and run the examples directly
	// instead of through exrun.
	if (mysqlpp::get_library_version() != MYSQLPP_HEADER_VERSION) {
		cerr << "Version mismatch: library is v" <<
				version_str(mysqlpp::get_library_version()) <<
				", headers are v" <<
				version_str(MYSQLPP_HEADER_VERSION) <<
				".  Are you running this" << endl <<
				"with exrun?  See README.examples." << endl;
		return 1;
	}
	
	// Connect to database server
	mysqlpp::Connection con;
	try {
		cout << "Connecting to database server..." << endl;
		if (!connect_to_db(argc, argv, con, "")) {
			return 1;
		}
	}
	catch (exception& er) {
		cerr << "Connection failed: " << er.what() << endl;
		return 1;
	}
	
	// Create new sample database, or re-create it.  We suppress
	// exceptions, because it's not an error if DB doesn't yet exist.
	bool new_db = false;
	{
		mysqlpp::NoExceptions ne(con);
		mysqlpp::Query query = con.query();
		if (con.select_db(kpcSampleDatabase)) {
			// Toss old table, if it exists.  If it doesn't, we don't
			// really care, as it'll get created next.
			cout << "Dropping existing sample data tables..." << endl;
			query.execute("drop table stock");
			query.execute("drop table images");
		}
		else {
			// Database doesn't exist yet, so create and select it.
			if (con.create_db(kpcSampleDatabase) &&
					con.select_db(kpcSampleDatabase)) {
				new_db = true;
			}
			else {
				cerr << "Error creating DB: " << con.error() << endl;
				return 1;
			}
		}
	}

	// Create sample data table within sample database.
	try {
		// Send the query to create the stock table and execute it.
		cout << "Creating stock table..." << endl;
		mysqlpp::Query query = con.query();
		query << 
				"CREATE TABLE stock (" <<
				"  item CHAR(20) NOT NULL, " <<
				"  num BIGINT, " <<
				"  weight DOUBLE, " <<
				"  price DOUBLE, " <<
				"  sdate DATE) " <<
				"ENGINE = InnoDB " <<
				"CHARACTER SET utf8 COLLATE utf8_general_ci";
		query.execute();

		// Set up the template query to insert the data.  The parse()
		// call tells the query object that this is a template and
		// not a literal query string.
		query << "insert into %5:table values (%0q, %1q, %2, %3, %4q)";
		query.parse();

		// Set the template query parameter "table" to "stock".
		query.def["table"] = "stock";

		// Notice that we don't give a sixth parameter in these calls,
		// so the default value of "stock" is used.  Also notice that
		// the first row is a UTF-8 encoded Unicode string!  All you
		// have to do to store Unicode data in recent versions of MySQL
		// is use UTF-8 encoding.
		cout << "Populating stock table..." << endl;
		query.execute("Nürnberger Brats", 97, 1.5, 8.79, "2005-03-10");
		query.execute("Pickle Relish", 87, 1.5, 1.75, "1998-09-04");
		query.execute("Hot Mustard", 73, .95, .97, "1998-05-25");
		query.execute("Hotdog Buns", 65, 1.1, 1.1, "1998-04-23");

		// Now create empty images table, for testing BLOB and auto-
		// increment column features.
		cout << "Creating empty images table..." << endl;
		query.reset();
		query << 
				"CREATE TABLE images (" <<
				"  id INT UNSIGNED NOT NULL AUTO_INCREMENT, " <<
				"  data BLOB, " <<
				"  PRIMARY KEY (id)" <<
				")";
		query.execute();

		// Report success
		cout << (new_db ? "Created" : "Reinitialized") <<
				" sample database successfully." << endl;
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return 1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return 1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return 1;
	}

	return 0;
}
Added examples/simple1.cc.



















































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include <iostream>
#include <iomanip>
#include <sqlplus.hh>

int main() {
  Connection con("mysql_cpp_data");
  // The full format for the Connection constructor is
  // Connection(cchar *db, cchar *host="", 
  //            cchar *user="", cchar *passwd="") 
  // You may need to specify some of them if the database is not on
  // the local machine or you database username is not the same as your
  // login name, etc..

  Query query = con.query();
  // This creates a query object that is bound to con.

  query << "select * from stock";
  // You can write to the query object like you would any other ostrem

  Result res = query.store();
  // Query::store() executes the query and returns the results

  cout << "Query: " << query.preview() << endl;
  // Query::preview() simply returns a string with the current query
  // string in it.

  cout << "Records Found: " << res.size() << endl << endl;
  
  Row row;
  cout.setf(ios::left);
  cout << setw(17) << "Item" 
       << setw(4)  << "Num"
       << setw(7)  << "Weight"
       << setw(7)  << "Price" 
       << "Date" << endl
       << endl;
  
  Result::iterator i;
  // The Result class has a read-only Random Access Iterator
  for (i = res.begin(); i != res.end(); i++) {
    row = *i;
    cout << setw(17) << row[0] 
	 << setw(4)  << row[1] 
	 << setw(7)  << row["weight"]
      // you can use either the index number or column name when
      // retrieving the colume data as demonstrated above.
	 << setw(7)  << row[3]
	 << row[4] << endl;
  }
  return 0;
}
Deleted examples/simple1.cpp.
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


































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 simple1.cpp - Example showing the simplest way to get data from a MySQL
    table with MySQL++.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;

int
main(int argc, char *argv[])
{
	// Connect to the sample database.
	mysqlpp::Connection con(false);
	if (!connect_to_db(argc, argv, con)) {
		return 1;
	}

	// Retrieve a subset of the sample stock table set up by resetdb
	mysqlpp::Query query = con.query();
	query << "select item from stock";
	mysqlpp::Result res = query.store();

	// Display the result set
	cout << "We have:" << endl;
	if (res) {
		mysqlpp::Row row;
		mysqlpp::Row::size_type i;
		for (i = 0; row = res.at(i); ++i) {
			cout << '\t' << row.at(0) << endl;
		}
	}
	else {
		cerr << "Failed to get item list: " << query.error() << endl;
		return 1;
	}

	return 0;
}
Deleted examples/simple2.cpp.
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















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 simple2.cpp - Retrieves the entire contents of the sample stock table
 	using a "store" query, and prints it out.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;

int
main(int argc, char *argv[])
{
	// Connect to the sample database.
	mysqlpp::Connection con(false);
	if (!connect_to_db(argc, argv, con)) {
		return 1;
	}

	// Retrieve the sample stock table set up by resetdb
	mysqlpp::Query query = con.query();
	query << "select * from stock";
	mysqlpp::Result res = query.store();

	// Display results
	if (res) {
		// Display header
		cout.setf(ios::left);
		cout << setw(21) << "Item" <<
				setw(10) << "Num" <<
				setw(10) << "Weight" <<
				setw(10) << "Price" <<
				"Date" << endl << endl;

		// Get each row in result set, and print its contents
		mysqlpp::Row row;
		mysqlpp::Row::size_type i;
		for (i = 0; row = res.at(i); ++i) {
			cout << setw(20) << row["item"] << ' ' <<
					setw(9) << row["num"] << ' ' <<
					setw(9) << row["weight"] << ' ' <<
					setw(9) << row["price"] << ' ' <<
					setw(9) << row["sdate"] <<
					endl;
		}
	}
	else {
		cerr << "Failed to get stock table: " << query.error() << endl;
		return 1;
	}

	return 0;
}
Deleted examples/simple3.cpp.
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















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 simple3.cpp - Example showing how to use the 'use' method of retrieving
	a table, as opposed to the more common 'store' method illustrated
	by the simple2 example.

 Copyright (c) 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>
#include <iomanip>

using namespace std;

int
main(int argc, char *argv[])
{
	// Connect to the sample database.
	mysqlpp::Connection con(false);
	if (!connect_to_db(argc, argv, con)) {
		return 1;
	}

	// Ask for all rows from the sample stock table set up by resetdb.
	// Unlike simple2 example, we don't store result set in memory.
	mysqlpp::Query query = con.query();
	query << "select * from stock";
	mysqlpp::ResUse res = query.use();

	// Retreive result rows one by one, and display them.
	if (res) {
		// Display header
		cout.setf(ios::left);
		cout << setw(21) << "Item" <<
				setw(10) << "Num" <<
				setw(10) << "Weight" <<
				setw(10) << "Price" <<
				"Date" << endl << endl;

		// Get each row in result set, and print its contents
		mysqlpp::Row row;
		while (row = res.fetch_row()) {
			cout << setw(20) << row["item"] << ' ' <<
					setw(9) << row["num"] << ' ' <<
					setw(9) << row["weight"] << ' ' <<
					setw(9) << row["price"] << ' ' <<
					setw(9) << row["sdate"] <<
					endl;
		}

		return 0;
	}
	else {
		cerr << "Failed to get stock item: " << query.error() << endl;
		return 1;
	}
}
Added examples/sinisa_ex.cc.
































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include <vector>
#include <string>
vector<string> yy;
#include <iostream>
#include <iomanip>
#include <mysql++>

int main() {
  Connection con(use_exceptions);
	try {
	con.real_connect ("","localhost","root","",3306,(int)0,60,NULL);
					
	cout << con.clinet_info() << endl << endl;
  Query query = con.query();

  query << "show databases";

  Result res = query.store();

  cout << "Query: " << query.preview() << endl;

  cout << "Records Found: " << res.size() << endl << endl;
  
  Row row;
  cout.setf(ios::left);
  cout << setw(17) << "Databases"  << endl << endl;
  
  Result::iterator i;
  for (i = res.begin(); i != res.end(); i++) {
    row = *i;
    cout << setw(17) << row[0]  << endl;
  }
	char database [] = "mysql";
  con.select_db (database);

  query << "show tables";

  res = query.store();

  cout << "Query: " << query.preview() << endl;

  cout << "Records Found: " << res.size() << endl << endl;
  
  cout.setf(ios::left);
  cout << setw(17) << "Tables"  << endl << endl;
			
  for (i = res.begin(); i != res.end(); i++) {
    row = *i;
		string xx(row[0]);
    cout << setw(17) << row[0]  << endl;
		yy.insert(yy.end(),xx);
  }
	for (unsigned int j = 0; j < yy.size();j++) {
		query << "describe " << yy[j] << "";
		cout << query.preview() << endl << endl;
		res = query.store();
		unsigned int columns = res.num_fields(), counter;
		cout << setw(15) << endl;
		for (counter = 0; counter < columns; counter++) {
			cout << setw(15) << res.names(counter) << "  ";
		}
		cout << endl << endl;
		for (i = res.begin(); i!=res.end();i++) {
			row = *i;
			for (counter = 0; counter < columns; counter++)  {
				cout << row[counter] << "  ";
			}
			cout << endl;
		}
	}
		query << "select * from user";
		res  =  query.store(); int columns =  res.num_fields();
		cout << query.preview() << endl << endl;
		cout << "fields = " << res.num_fields() << "rows = " << res.size() << endl;
		for (i = res.begin(); i!=res.end();i++) {
			row = *i;
			for (int counter = 0; counter < columns; counter++)  {
				cout << row[counter] << "  ";
			}
			cout << endl;
		}
  } catch (BadQuery er){ // handle any connection 
                         // or query errors that may come up
    cerr << "Error: " << er.error << " " << con.errnum() << endl;
    return -1;

  } catch (BadConversion er) {
    // we still need to cache bad conversions incase something goes 
    // wrong when the data is converted into stock
    cerr << "Error: Tried to convert \"" << er.data << "\" to a \""
	 << er.type_name << "\"." << endl;
    return -1;
  }

}

Deleted examples/stock.h.
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
















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 stock.h - Declares the stock SSQLS used by several of the examples.
 
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include <mysql++.h>
#include <custom.h>

#include <string>

// The following is calling a very complex macro which will create
// "struct stock", which has the member variables:
//
//   sql_char item;
//   ...
//   sql_date sdate;
//
// plus methods to help populate the class from a MySQL row.  See the
// SSQLS sections in the user manual for further details.
sql_create_5(stock,
	1, 5, // The meaning of these values is covered in the user manual
	mysqlpp::sql_char, item,
	mysqlpp::sql_bigint, num,
	mysqlpp::sql_double, weight,
	mysqlpp::sql_double, price,
	mysqlpp::sql_date, sdate)

Deleted examples/store_if.cpp.
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



































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 store_if.cpp - Demonstrates Query::store_if(), showing only the rows
	from the sample table with prime quantities.  This isn't intended
	to be useful, only to show how you can do result set filtering that
	outstrips the power of SQL.

 Copyright (c) 2005-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"
#include "stock.h"

#include <mysql++.h>

#include <iostream>

#include <math.h>


// Define a functor for testing primality.
struct is_prime
{
	bool operator()(const stock& s)
	{
		if ((s.num == 2) || (s.num == 3)) {
			return true;	// 2 and 3 are trivial cases
		}
		else if ((s.num < 2) || ((s.num % 2) == 0)) {
			return false;	// can't be prime if < 2 or even
		}
		else {
			// The only possibility left is that it's divisible by an
			// odd number that's less or equal to its square root.
			for (int i = 3; i <= sqrt(double(s.num)); i += 2) {
				if ((s.num % i) == 0) {
					return false;
				}
			}
			return true;
		}
	}
};


int
main(int argc, char *argv[])
{
	try {
		// Connect to the sample database
		mysqlpp::Connection con;
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Collect the stock items with prime quantities
		std::vector<stock> results;
		mysqlpp::Query query = con.query();
		query.store_if(results, stock(), is_prime());

		// Show the results
		print_stock_header(results.size());
		std::vector<stock>::const_iterator it;
		for (it = results.begin(); it != results.end(); ++it) {
			print_stock_row(it->item.c_str(), it->num, it->weight,
					it->price, it->sdate);
		}
	}
	catch (const mysqlpp::BadQuery& e) {
		// Something went wrong with the SQL query.
		std::cerr << "Query failed: " << e.what() << std::endl;
		return 1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		std::cerr << "Error: " << er.what() << std::endl;
		return 1;
	}

	return 0;
}
Deleted examples/tquery.cpp.
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
























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 tquery.cpp - Example similar to custom3.cpp, except that it uses
	template queries instead of SSQLS.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <iostream>

using namespace std;

int
main(int argc, char *argv[])
{
	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Build a template query to retrieve a stock item given by
		// item name.
		mysqlpp::Query query = con.query();
		query << "select * from stock where item = %0q";
		query.parse();

		// Retrieve an item added by resetdb; it won't be there if
		// tquery or custom3 is run since resetdb.
		mysqlpp::Result res1 = query.store("Nürnberger Brats");
		if (res1.empty()) {
			throw mysqlpp::BadQuery("UTF-8 bratwurst item not found in "
					"table, run resetdb");
		}

		// Replace the proper German name with a 7-bit ASCII
		// approximation using a different template query.
		query.reset();
		query << "update stock set item = %0q where item = %1q";
		query.parse();
		mysqlpp::ResNSel res2 = query.execute("Nuerenberger Bratwurst",
				res1.at(0).at(0).c_str());

		// Print the new table contents.
		print_stock_table(query);
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted examples/usequery.cpp.
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















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 usequery.cpp - Same as simple3 example, only with exceptions enabled.
	The end of the result set is signalled differently in this case.

 Copyright (c) 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <mysql++.h>

#include <iostream>

int
main(int argc, char *argv[])
{
	try {
		// Connect to the sample database
		mysqlpp::Connection con;
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Build query to retrieve the entire stock table
		mysqlpp::Query query = con.query();
		query << "select * from stock";

		// Execute the query, but don't save results in memory
		mysqlpp::ResUse res = query.use();
		if (!res) {
			std::cerr << "Result set is empty!" << std::endl;
			return 1;
		}

		// Iterate through result set, printing each row.
		mysqlpp::Row r;
		while (r = res.fetch_row()) {
			print_stock_row(r);
		}
	}
	catch (const mysqlpp::BadQuery& e) {
		// Something went wrong with the SQL query.
		std::cerr << "Query failed: " << e.what() << std::endl;
		return 1;
	}
	catch (const mysqlpp::EndOfResults&) {
		// Last query result received.  Exit normally.
		return 0;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		std::cerr << "Error: " << er.what() << std::endl;
		return 1;
	}

	// Shouldn't happen!  Program should either error out through one of
	// the "return 1" cases above, or successfully walk off the end of
	// the result set and go through the EndOfResults path above.
	return 2;
}
Added examples/util.cc.








































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include <iostream>
#include <iomanip>
#include "util.hh"

void print_stock_table(Query& query) {
  query.reset();
  query << "select * from stock";
  // You can write to the query object like you would any other ostrem

  Result res = query.store();
  // Query::store() executes the query and returns the results

  cout << "Query: " << query.preview() << endl;
  // Query::preview() simply returns a string with the current query
  // string in it.

  cout << "Records Found: " << res.size() << endl << endl;
  
  Row row;
  cout.setf(ios::left);
  cout << setw(17) << "Item" 
       << setw(4)  << "Num"
       << setw(7)  << "Weight"
       << setw(7)  << "Price" 
       << "Date" << endl
       << endl;
  
  Result::iterator i;
  // The Result class has a read-only Random Access Iterator
  for (i = res.begin(); i != res.end(); i++) {
    row = *i;
    cout << setw(17) << row[0] 
	 << setw(4)  << row[1] 
	 << setw(7)  << row["weight"]
      // you can use either the index number or column name when
      // retrieving the colume data as demonstrated above.
	 << setw(7)  << row[3]
	 << row[4] << endl;
  }
}
Deleted examples/util.cpp.
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





















































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 util.cpp - Utility functions required by several of the example
 	programs.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "util.h"

#include <iostream>
#include <iomanip>

// This include isn't actually needed here.  It's just a test of the
// feature added in v2.1 allowing an SSQLS to be defined in multiple
// modules without having a multiply-defined static variable error.
// The test is disabled for VC++ 2003, which doesn't support the
// feature.
#if !defined(_MSC_VER) || _MSC_VER >= 1400
#	define MYSQLPP_SSQLS_NO_STATICS
#	include "stock.h"		
#endif

using namespace std;

const char* kpcSampleDatabase = "mysql_cpp_data";


//// print_stock_header ////////////////////////////////////////////////
// Display a header suitable for use with print_stock_rows().

void
print_stock_header(int rows)
{
	cout << "Records found: " << rows << endl << endl;
	cout.setf(ios::left);
	cout << setw(21) << "Item" <<
			setw(10) << "Num" <<
			setw(10) << "Weight" <<
			setw(10) << "Price" <<
			"Date" << endl << endl;
}


//// print_stock_row ///////////////////////////////////////////////////
// Print out a row of data from the stock table, in a format compatible
// with the header printed out in the previous function.

void
print_stock_row(const mysqlpp::sql_char& item, mysqlpp::sql_bigint num,
		mysqlpp::sql_double weight, mysqlpp::sql_double price,
		const mysqlpp::sql_date& date)
{
	char buf[100];
	cout << setw(20) << item << ' ' <<
			setw(9) << num << ' ' <<
			setw(9) << weight << ' ' <<
			setw(9) << price << ' ' <<
			date << endl;
}


//// print_stock_row ///////////////////////////////////////////////////
// Take a Row from the example 'stock' table, break it up into fields,
// and call the above version of this function.

void
print_stock_row(const mysqlpp::Row& row)
{
	// The brief code below illustrates several aspects of the library
	// worth noting:
	//
	// 1. You can subscript a row by integer (position of the field in
	// the row) or by string (name of field in the row).  The former is
	// more efficient, while the latter trades some efficiency for
	// robustness in the face of schema changes.  (Consider using SSQLS
	// if you need a tradeoff in between these two positions.)
	// 
	// 2. You can also get at a row's field's with Row::at(), which is
	// much like Row::operator[](int).  Besides the syntax difference,
	// the only practical difference is that only at() can access field
	// 0: this is because '0' can be converted to both int and to const
	// char*, so the compiler rightly complains that it can't decide
	// which overload to call.
	//
	// 3. Notice that we make an explicit temporary copy of the first
	// field, which is the only string field.  We must tolerate the
	// inefficiency of this copy, because Row::operator[] returns a
	// ColData object, which goes away after it is converted to some
	// other form.  So, while we could have made print_stock_row()
	// take a const char* argument (as past versions mistakenly did!)
	// this would result in a dangling pointer, since it points into the
	// ColData object, which is dead by the time the pointer is
	// evaluated in print_stock_row().  It will probably even work this
	// way, but like any memory bug, it can wreak subtle havoc.
	std::string item(row.at(0));
	print_stock_row(item, row["num"], row[2], row[3], row[4]);
}


//// print_stock_rows //////////////////////////////////////////////////
// Print out a number of rows from the example 'stock' table.

void
print_stock_rows(mysqlpp::Result& res)
{
	print_stock_header(res.size());

	// Use the Result class's read-only random access iterator to walk
	// through the query results.
	mysqlpp::Result::iterator i;
	for (i = res.begin(); i != res.end(); ++i) {
		// Notice that a dereferenced result iterator can be converted
		// to a Row object, which makes for easier element access.
		print_stock_row(*i);
	}
}


//// get_stock_table ///////////////////////////////////////////////////
// Retreive the entire contents of the example 'stock' table.

void
get_stock_table(mysqlpp::Query& query, mysqlpp::Result& res)
{
	// Reset the query object, in case we're re-using it.
	query.reset();

	// You can write to the query object like you would any ostream.
	query << "select * from stock";

	// Show the query string.  If you call preview(), it must be before
	// you call execute() or store() or use().
	cout << "Query: " << query.preview() << endl;

	// Execute the query, storing the results in memory.
	res = query.store();
}


//// print_stock_table /////////////////////////////////////////////////
// Simply retrieve and print the entire contents of the stock table.

void
print_stock_table(mysqlpp::Query& query)
{
	mysqlpp::Result res;
	get_stock_table(query, res);
	print_stock_rows(res);
}


//// print_usage ///////////////////////////////////////////////////////
// Show the program's usage message

void
print_usage(const char* program_name, const char* extra_parms)
{
	cout << "usage: " << program_name <<
			" [host [user [password [port]]]] " << extra_parms << endl;
	cout << endl;
	cout << "    If no arguments are given, connects to database "
			"server on localhost" << endl;
	cout << "    using your user name and no password.  You may give "
			"any number of" << endl;
	cout << "    these arguments, but they must be in the order "
			"listed, and you" << endl;
	cout << "    cannot skip preceding arguments." << endl;
	if (strlen(extra_parms) > 0) {
		cout << endl;
		cout << "    The extra parameter " << extra_parms <<
				" is required, regardless of which" << endl;
		cout << "    other arguments you pass." << endl;
	}
	cout << endl;
}


//// connect_to_db /////////////////////////////////////////////////////
// Establishes a connection to a MySQL database server, optionally
// attaching to database kdb.  This is basically a command-line parser
// for the examples, since the example programs' arguments give us the
// information we need to establish the server connection.

bool
connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
		const char *kdb)
{
	if (argc < 1) {
		cerr << "Bad argument count: " << argc << '!' << endl;
		return false;
	}

	if (!kdb) {
		kdb = kpcSampleDatabase;
	}

	if ((argc > 1) && (argv[1][0] == '-')) {
		print_usage(argv[0]);
		return false;
	}

	if (argc == 1) {
		con.connect(kdb);
	}
	else if (argc == 2) {
		con.connect(kdb, argv[1]);
	}
	else if (argc == 3) {
		con.connect(kdb, argv[1], argv[2]);
	}
	else if (argc == 4) {
		con.connect(kdb, argv[1], argv[2], argv[3]);
	}
	else if (argc >= 5) {
		con.connect(kdb, argv[1], argv[2], argv[3], atoi(argv[4]));
	}

	if (con) {
		return true;
	}
	else {
		cerr << "Database connection failed: " << con.error() << endl;
		return false;
	}
}
Deleted examples/util.h.
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

















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 util.h - Declares functions and such required by several of the
 	example programs.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#if !defined(MYSQLPP_UTIL_H)
#define MYSQLPP_UTIL_H

#include <mysql++.h>

extern const char* kpcSampleDatabase;

void print_stock_header(int rows);
void print_stock_row(const mysqlpp::Row& r);
void print_stock_row(const mysqlpp::sql_char& item,
		mysqlpp::sql_bigint num, mysqlpp::sql_double weight,
		mysqlpp::sql_double price, const mysqlpp::sql_date& date);
void print_stock_rows(mysqlpp::Result& res);
void print_stock_table(mysqlpp::Query& query);
void get_stock_table(mysqlpp::Query& query, mysqlpp::Result& res);
void print_usage(const char* program_name,
		const char* extra_parms = "");
bool connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
		const char* kdb = 0);

#endif // !defined(MYSQLPP_UTIL_H)

Added examples/util.hh.








1
2
3
4
5
6
7
8
+
+
+
+
+
+
+
+
#ifndef _util_hh_
#define _util_hh_

#include <sqlplus.hh>

void print_stock_table(Query& query);

#endif
Deleted examples/vstudio/mfc/mfc.cpp.
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






















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 mfc.cpp - Skeletal main module of the MySQL++ MFC example program.
	Nothing interesting to see here.  Move along to mfc_dlg.cpp, folks.

 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others 
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stdafx.h"
#include "mfc.h"
#include "mfc_dlg.h"

CApp gApplication;

BOOL CApp::InitInstance()
{
	// Set up Windows commomn controls
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();

	// Initialize Winsock for MySQL communication, start GUI
	if (AfxSocketInit()) {
		CExampleDlg dlg;
		m_pMainWnd = &dlg;
		dlg.DoModal();
	}
	else {
		AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
	}

	return FALSE;
}
Deleted examples/vstudio/mfc/mfc.h.
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


































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 mfc.cpp - Declares the MFC application object.  Nothing interesting to
	see here.  Move along to mfc_dlg.cpp, folks.

 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others 
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#pragma once

class CApp : public CWinApp
{
public:
	CApp() { }
	virtual BOOL InitInstance();
};
Deleted examples/vstudio/mfc/mfc.rc.
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







































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
    "LANGUAGE 9, 1\r\n"
    "#pragma code_page(1252)\r\n"
    "#include ""afxres.rc""     // Standard components\r\n"
    "#endif\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_MFC_DIALOG DIALOGEX 0, 0, 210, 105
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW
CAPTION "MySQL++ MFC Example"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    EDITTEXT        IDC_SERVER_EDIT,51,7,94,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_USER_EDIT,51,24,94,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_PASSWORD_EDIT,51,41,94,14,ES_PASSWORD | ES_AUTOHSCROLL
    DEFPUSHBUTTON   "Connect!",IDC_CONNECT_BUTTON,153,7,50,14
    PUSHBUTTON      "Close",IDCANCEL,153,25,50,16
    LISTBOX         IDC_RESULTS_LIST,51,58,94,40,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_DISABLED | WS_VSCROLL
    RTEXT           "Server:",IDC_STATIC,7,7,40,8
    RTEXT           "User name:",IDC_STATIC,7,24,40,8
    RTEXT           "Password:",IDC_STATIC,7,41,40,8
    RTEXT           "Results:",IDC_STATIC,7,58,40,8
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_MFC_DIALOG, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 203
        TOPMARGIN, 7
        BOTTOMMARGIN, 98
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE 
BEGIN
    IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed."
END

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#pragma code_page(1252)
#include "afxres.rc"     // Standard components
#endif

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

Deleted examples/vstudio/mfc/mfc_dlg.cpp.
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



















































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 mfc_dlg.cpp - Defines the dialog box behavior for the MySQL++ MFC
	example.

 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others 
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stdafx.h"
#include "mfc_dlg.h"

#include <mysql++.h>

BEGIN_MESSAGE_MAP(CExampleDlg, CDialog)
	ON_BN_CLICKED(IDC_CONNECT_BUTTON, &CExampleDlg::OnBnClickedConnectButton)
END_MESSAGE_MAP()


//// ctor //////////////////////////////////////////////////////////////

CExampleDlg::CExampleDlg(CWnd* pParent) :
CDialog(IDD_MFC_DIALOG, pParent)
{
	LoadDefaults();
}


//// AddMessage ////////////////////////////////////////////////////////
// Inserts the given string at the end of the list box we're using for
// output to the user.

void 
CExampleDlg::AddMessage(LPCTSTR pcMessage)
{
	ResultsList.InsertString(-1, pcMessage);
}


//// DoDataExchange ////////////////////////////////////////////////////
// Transfer data from the controls into our member variables

void
CExampleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_SERVER_EDIT, sServerAddress);
	DDX_Text(pDX, IDC_USER_EDIT, sUserName);
	DDX_Text(pDX, IDC_PASSWORD_EDIT, sPassword);
	DDX_Control(pDX, IDC_RESULTS_LIST, ResultsList);
}


//// LoadDefaults //////////////////////////////////////////////////////
// Load default input values from registry, if they exist.

void
CExampleDlg::LoadDefaults()
{
	HKEY key = OpenSettingsRegistryKey();
	if (key) {
		TCHAR acSetting[100];
		if (LoadSetting(key, _T("user"), acSetting, sizeof(acSetting))) {
			sUserName = acSetting;
		}
		if (LoadSetting(key, _T("server"), acSetting, sizeof(acSetting))) {
			sServerAddress = acSetting;
		}
		RegCloseKey(key);
	}

	if (sUserName.IsEmpty()) {
		TCHAR acUserName[100];
		DWORD nBufferSize = sizeof(acUserName);
		if (GetUserName(acUserName, &nBufferSize)) {
			sUserName = acUserName;
		}
	}
	if (sServerAddress.IsEmpty()) {
		sServerAddress = _T("localhost");
	}
}


//// LoadSetting ///////////////////////////////////////////////////////
// Loads up the value of the named registry value underneath the given
// key and returns it in pcValue.

bool
CExampleDlg::LoadSetting(HKEY key, LPCTSTR pcName, LPTSTR pcValue,
		DWORD nValueSize)
{
	return RegQueryValueEx(key, pcName, 0, 0, LPBYTE(pcValue),
			&nValueSize) == ERROR_SUCCESS;
}


//// OnBnClickedConnectButton //////////////////////////////////////////
// This is essentially the same thing as examples/simple1.cpp

void
CExampleDlg::OnBnClickedConnectButton()
{
	WCHAR awcTempBuf[100];
	const int kTempBufSize = sizeof(awcTempBuf) / sizeof(awcTempBuf[0]);

	// Pull user input into our member variables
	UpdateData(TRUE);

	// Clear out the results list, in case this isn't the first time
	// we've come in here.
	ResultsList.ResetContent();

	// Translate the Unicode text we get from the UI into the UTF-8 form
	// that MySQL wants.
	const int kInputBufSize = 100;
	char acServerAddress[kInputBufSize];
	char acUserName[kInputBufSize];
	char acPassword[kInputBufSize];
	ToUTF8(acServerAddress, kInputBufSize, sServerAddress);
	ToUTF8(acUserName, kInputBufSize, sUserName);
	ToUTF8(acPassword, kInputBufSize, sPassword);

	// Connect to the sample database.
	mysqlpp::Connection con(false);
	if (!con.connect("mysql_cpp_data", acServerAddress, acUserName,
			acPassword)) {
		AddMessage(_T("Failed to connect to server:"));
		if (ToUCS2(awcTempBuf, kTempBufSize, con.error())) {
			AddMessage(awcTempBuf);
		}
		return;
	}

	// Retrieve a subset of the sample stock table set up by resetdb
	mysqlpp::Query query = con.query();
	query << "select item from stock";
	mysqlpp::Result res = query.store();

	if (res) {
		// Display the result set
		mysqlpp::Row row;
		for (mysqlpp::Row::size_type i = 0; row = res.at(i); ++i) {
			if (ToUCS2(awcTempBuf, kTempBufSize, row.at(0))) {
				AddMessage(awcTempBuf);
			}
		}

		// Retreive was successful, so save user inputs now
		SaveInputs();
	}
	else {
		// Retreive failed
		AddMessage(_T("Failed to get item list:"));
		if (ToUCS2(awcTempBuf, kTempBufSize, query.error().c_str())) {
			AddMessage(awcTempBuf);
		}
	}
}


//// OpenSettingsRegistryKey ///////////////////////////////////////////

HKEY
CExampleDlg::OpenSettingsRegistryKey()
{
	HKEY key1, key2;
	if ((RegOpenKey(HKEY_CURRENT_USER, _T("Software"), &key1) ==
			ERROR_SUCCESS) && (RegCreateKey(key1,
			_T("MySQL++ Examples"), &key2) == ERROR_SUCCESS)) {
		RegCloseKey(key1);
		return key2;
	}
	else {
		return 0;
	}
}


//// SaveInputs ////////////////////////////////////////////////////////
// Saves the input fields' values to the registry, except for the
// password field.

bool
CExampleDlg::SaveInputs()
{
	HKEY key = OpenSettingsRegistryKey();
	if (key) {
		SaveSetting(key, _T("user"), sUserName);
		SaveSetting(key, _T("server"), sServerAddress);
		RegCloseKey(key);
		return true;
	}
	else {
		return false;
	}
}


//// SaveSetting ///////////////////////////////////////////////////////
// Saves the given value as a named entry under the given registry key.

bool
CExampleDlg::SaveSetting(HKEY key, LPCTSTR pcName, LPCTSTR pcValue)
{
	DWORD nBytes = DWORD(sizeof(TCHAR) * (_tcslen(pcValue) + 1));
	return RegSetValueEx(key, pcName, 0, REG_SZ, LPBYTE(pcValue),
			nBytes) == ERROR_SUCCESS;
}


//// ToUCS2 ////////////////////////////////////////////////////////////
// Convert a C string in UTF-8 format to UCS-2 format.

bool
CExampleDlg::ToUCS2(LPTSTR pcOut, int nOutLen, const char* kpcIn)
{
	if (strlen(kpcIn) > 0) {
		// Do the conversion normally
		return MultiByteToWideChar(CP_UTF8, 0, kpcIn, -1, pcOut,
				nOutLen) > 0;
	}
	else if (nOutLen > 1) {
		// Can't distinguish no bytes copied from an error, so handle
		// an empty input string as a special case.
		_tccpy(pcOut, _T(""));
		return true;
	}
	else {
		// Not enough room to do anything!
		return false;
	}
}


//// ToUTF8 ////////////////////////////////////////////////////////////
// Convert a UCS-2 multibyte string to the UTF-8 format required by
// MySQL, and thus MySQL++.

bool
CExampleDlg::ToUTF8(char* pcOut, int nOutLen, LPCWSTR kpcIn)
{
	if (_tcslen(kpcIn) > 0) {
		// Do the conversion normally
		return WideCharToMultiByte(CP_UTF8, 0, kpcIn, -1, pcOut,
				nOutLen, 0, 0) > 0;
	}
	else if (nOutLen > 0) {
		// Can't distinguish no bytes copied from an error, so handle
		// an empty input string as a special case.
		*pcOut = '\0';
		return true;
	}
	else {
		// Not enough room to do anything!
		return false;
	}
}
Deleted examples/vstudio/mfc/mfc_dlg.h.
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


























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 mfc_dlg.h - Declares the dialog class for the MySQL++ MFC example.

 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others 
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#pragma once
#include "afxwin.h"
#include "resource.h"

class CExampleDlg : public CDialog
{
public:
	//// Public interface
	CExampleDlg(CWnd* pParent = 0);

	//// Public data
	CString sServerAddress;
	CString sUserName;
	CString sPassword;
	CListBox ResultsList;

protected:
	//// Internal support functions
	void AddMessage(LPCTSTR pcMessage);
	void DoDataExchange(CDataExchange* pDX);
	void LoadDefaults();
	bool LoadSetting(HKEY key, LPCTSTR pcName, LPTSTR pcValue,
			DWORD nValueSize);
	HKEY OpenSettingsRegistryKey();
	bool SaveInputs();
	bool SaveSetting(HKEY key, LPCTSTR pcName, LPCTSTR pcValue);
	bool ToUCS2(LPTSTR pcOut, int nOutLen, const char* kpcIn);
	bool ToUTF8(char* pcOut, int nOutLen, LPCWSTR kpcIn);

	//// Message map
	afx_msg void OnBnClickedConnectButton();
	DECLARE_MESSAGE_MAP()
};
Deleted examples/vstudio/mfc/resource.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22






















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by mfc.rc
//
#define IDD_MFC_DIALOG                  102
#define IDP_SOCKETS_INIT_FAILED         103
#define IDC_SERVER_EDIT                 1000
#define IDC_PASSWORD_EDIT               1001
#define IDC_USER_EDIT                   1002
#define IDC_RESULTS_LIST                1003
#define IDC_CONNECT_BUTTON              1004

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1005
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
Deleted examples/vstudio/mfc/stdafx.h.
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






















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 stdafx.h - Common include file to bring in MFC support and other
	basics.

 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others 
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#endif

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER				// Allow use of features specific to Windows XP or later.
#define WINVER 0x0501		// Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
#endif						

#ifndef _WIN32_WINDOWS		// Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxcmn.h>			// MFC support for Windows Common Controls
#include <afxsock.h>		// MFC socket extensions

Deleted examples/vstudio/wforms/AssemblyInfo.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;

[assembly:AssemblyTitleAttribute("wforms")];
[assembly:AssemblyDescriptionAttribute("")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("the MySQL++ project")];
[assembly:AssemblyProductAttribute("MySQL++ Windows Forms Example")];
[assembly:AssemblyCopyrightAttribute("Copyright © 2007 by ETR, Inc.")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
Deleted examples/vstudio/wforms/MainForm.h.
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


























































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 MainForm.cpp - Defines the dialog box behavior for the MySQL++ C++/CLI
	Windows Forms example.

 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others 
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#pragma once

#include <mysql++.h>

namespace wforms {

	using namespace Microsoft::Win32;
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	public ref class MainForm : public System::Windows::Forms::Form
	{
	public:
		MainForm()
		{
			InitializeComponent();
			LoadDefaults();
		}

	protected:
		~MainForm()
		{
			if (components) {
				delete components;
			}
		}

	private:
		// Insert a text string into the output list control
		Void AddMessage(String^ msg)
		{
			resultsList_->Items->Add(msg);
		}

		// Handle Close button click by shutting down application
		Void CloseButton_Click(Object^ sender, EventArgs^ e)
		{
			Application::Exit();
		}
		
		// Handle Connect button click.  The body of this function is
		// essentially the same as the simple2 command line example, with
		// some GUI overhead.
		Void ConnectButton_Click(Object^ sender, EventArgs^ e)
		{
			// Clear out the results list, in case this isn't the first time
			// we've come in here.
			resultsList_->Items->Clear();

			// Translate the Unicode text we get from the UI into the UTF-8
			// form that MySQL wants.
			const int kInputBufSize = 100;
			char acServerAddress[kInputBufSize];
			char acUserName[kInputBufSize];
			char acPassword[kInputBufSize];
			ToUTF8(acServerAddress, kInputBufSize, serverAddress_->Text);
			ToUTF8(acUserName, kInputBufSize, userName_->Text);
			ToUTF8(acPassword, kInputBufSize, password_->Text);

			// Connect to the sample database.
			mysqlpp::Connection con(false);
			if (!con.connect("mysql_cpp_data", acServerAddress, acUserName,
					acPassword)) {
				AddMessage("Failed to connect to server:");
				AddMessage(gcnew String(con.error()));
				return;
			}

			// Retrieve a subset of the sample stock table set up by resetdb
			mysqlpp::Query query = con.query();
			query << "select item from stock";
			mysqlpp::Result res = query.store();

			if (res) {
				// Display the result set
				mysqlpp::Row row;
				for (mysqlpp::Row::size_type i = 0; row = res.at(i); ++i) {
					AddMessage(ToUCS2(row.at(0)));
				}

				// Retreive was successful, so save user inputs now
				SaveInputs();
			}
			else {
				// Retreive failed
				AddMessage("Failed to get item list:");
				AddMessage(ToUCS2(query.error().c_str()));
			}
		}

		// Load the default input field values, if there are any
		Void LoadDefaults()
		{
			RegistryKey^ settings = OpenSettingsRegistryKey();
			if (settings) {
				userName_->Text = LoadSetting(settings, L"user");
				serverAddress_->Text = LoadSetting(settings, L"server");
			}
			
			if (String::IsNullOrEmpty(userName_->Text)) {
				userName_->Text = Environment::UserName;
			}
			if (String::IsNullOrEmpty(serverAddress_->Text)) {
				serverAddress_->Text = L"localhost";
			}
		}

		// Returns a setting from underneath the given registry key.
		// Assumes that it's a string value under the MySQL++ examples' 
		// settings area.
		String^ LoadSetting(RegistryKey^ key, String^ name)
		{
			return (String^)key->GetValue(name);
		}

		// Returns a reference to the MySQL++ examples' settings area in the
		// registry.
		RegistryKey^ OpenSettingsRegistryKey()
		{
			RegistryKey^ key = Registry::CurrentUser->OpenSubKey(L"Software",
					true);
			return key ? key->CreateSubKey(L"MySQL++ Examples") : nullptr;
		}

		// Saves the input fields' values to the registry, except for the
		// password field.
		Void SaveInputs()
		{
			RegistryKey^ settings = OpenSettingsRegistryKey();
			if (settings) {
				SaveSetting(settings, "user", userName_->Text);
				SaveSetting(settings, "server", serverAddress_->Text);
			}			
		}

		// Saves the given value as a named entry under the given registry
		// key.
		Void SaveSetting(RegistryKey^ key, String^ name, String^ value)
		{
			key->SetValue(name, value);
		}

		// Takes a string in the .NET platform's native Unicode format and
		// copies it to the given C string buffer in UTF-8 encoding.
		Void ToUTF8(char* pcOut, int nOutLen, String^ sIn)
		{
			array<Byte>^ bytes = System::Text::Encoding::UTF8->GetBytes(sIn);
			nOutLen = Math::Min(nOutLen - 1, bytes->Length);
			System::Runtime::InteropServices::Marshal::Copy(bytes, 0, 
				IntPtr(pcOut), nOutLen);
			pcOut[nOutLen] = '\0';
		}

		// Takes the given C string encoded in UTF-8 and converts it to a
		// Unicode string in the .NET platform's native Unicode encoding.
		String^ ToUCS2(const char* utf8)
		{
			return gcnew String(utf8, 0, strlen(utf8), 
					System::Text::Encoding::UTF8);
		}

	private: System::Windows::Forms::TextBox^ serverAddress_;
	private: System::Windows::Forms::TextBox^ password_;
	private: System::Windows::Forms::TextBox^ userName_;
	private: System::Windows::Forms::ListBox^ resultsList_;
	private: System::Windows::Forms::Button^ connectButton_;
	private: System::Windows::Forms::Button^ closeButton_;
	private: System::ComponentModel::Container^ components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			System::Windows::Forms::Label^  label1;
			System::Windows::Forms::Label^  label2;
			System::Windows::Forms::Label^  label3;
			System::Windows::Forms::Label^  label4;
			this->serverAddress_ = (gcnew System::Windows::Forms::TextBox());
			this->password_ = (gcnew System::Windows::Forms::TextBox());
			this->userName_ = (gcnew System::Windows::Forms::TextBox());
			this->resultsList_ = (gcnew System::Windows::Forms::ListBox());
			this->connectButton_ = (gcnew System::Windows::Forms::Button());
			this->closeButton_ = (gcnew System::Windows::Forms::Button());
			label1 = (gcnew System::Windows::Forms::Label());
			label2 = (gcnew System::Windows::Forms::Label());
			label3 = (gcnew System::Windows::Forms::Label());
			label4 = (gcnew System::Windows::Forms::Label());
			this->SuspendLayout();
			// 
			// label1
			// 
			label1->AutoSize = true;
			label1->Location = System::Drawing::Point(29, 13);
			label1->Name = L"label1";
			label1->Size = System::Drawing::Size(41, 13);
			label1->TabIndex = 6;
			label1->Text = L"Server:";
			label1->TextAlign = System::Drawing::ContentAlignment::TopRight;
			// 
			// label2
			// 
			label2->AutoSize = true;
			label2->Location = System::Drawing::Point(9, 39);
			label2->Name = L"label2";
			label2->Size = System::Drawing::Size(61, 13);
			label2->TabIndex = 7;
			label2->Text = L"User name:";
			label2->TextAlign = System::Drawing::ContentAlignment::TopRight;
			// 
			// label3
			// 
			label3->AutoSize = true;
			label3->Location = System::Drawing::Point(14, 65);
			label3->Name = L"label3";
			label3->Size = System::Drawing::Size(56, 13);
			label3->TabIndex = 8;
			label3->Text = L"Password:";
			label3->TextAlign = System::Drawing::ContentAlignment::TopRight;
			// 
			// label4
			// 
			label4->AutoSize = true;
			label4->Location = System::Drawing::Point(25, 92);
			label4->Name = L"label4";
			label4->Size = System::Drawing::Size(45, 13);
			label4->TabIndex = 9;
			label4->Text = L"Results:";
			label4->TextAlign = System::Drawing::ContentAlignment::TopRight;
			// 
			// serverAddress_
			// 
			this->serverAddress_->Location = System::Drawing::Point(70, 9);
			this->serverAddress_->Name = L"serverAddress_";
			this->serverAddress_->Size = System::Drawing::Size(139, 20);
			this->serverAddress_->TabIndex = 0;
			// 
			// password_
			// 
			this->password_->Location = System::Drawing::Point(70, 61);
			this->password_->Name = L"password_";
			this->password_->Size = System::Drawing::Size(139, 20);
			this->password_->TabIndex = 2;
			this->password_->UseSystemPasswordChar = true;
			// 
			// userName_
			// 
			this->userName_->Location = System::Drawing::Point(70, 35);
			this->userName_->Name = L"userName_";
			this->userName_->Size = System::Drawing::Size(139, 20);
			this->userName_->TabIndex = 1;
			// 
			// resultsList_
			// 
			this->resultsList_->Enabled = false;
			this->resultsList_->FormattingEnabled = true;
			this->resultsList_->Location = System::Drawing::Point(70, 88);
			this->resultsList_->Name = L"resultsList_";
			this->resultsList_->Size = System::Drawing::Size(228, 95);
			this->resultsList_->TabIndex = 3;
			this->resultsList_->TabStop = false;
			// 
			// connectButton_
			// 
			this->connectButton_->Location = System::Drawing::Point(224, 9);
			this->connectButton_->Name = L"connectButton_";
			this->connectButton_->Size = System::Drawing::Size(75, 23);
			this->connectButton_->TabIndex = 3;
			this->connectButton_->Text = L"Connect!";
			this->connectButton_->UseVisualStyleBackColor = true;
			this->connectButton_->Click += gcnew System::EventHandler(this, &MainForm::ConnectButton_Click);
			// 
			// closeButton_
			// 
			this->closeButton_->DialogResult = System::Windows::Forms::DialogResult::Cancel;
			this->closeButton_->Location = System::Drawing::Point(224, 38);
			this->closeButton_->Name = L"closeButton_";
			this->closeButton_->Size = System::Drawing::Size(75, 23);
			this->closeButton_->TabIndex = 4;
			this->closeButton_->Text = L"Close";
			this->closeButton_->UseVisualStyleBackColor = true;
			this->closeButton_->Click += gcnew System::EventHandler(this, &MainForm::CloseButton_Click);
			// 
			// MainForm
			// 
			this->AcceptButton = this->connectButton_;
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->CancelButton = this->closeButton_;
			this->ClientSize = System::Drawing::Size(310, 192);
			this->ControlBox = false;
			this->Controls->Add(label4);
			this->Controls->Add(label3);
			this->Controls->Add(label2);
			this->Controls->Add(label1);
			this->Controls->Add(this->closeButton_);
			this->Controls->Add(this->connectButton_);
			this->Controls->Add(this->resultsList_);
			this->Controls->Add(this->userName_);
			this->Controls->Add(this->password_);
			this->Controls->Add(this->serverAddress_);
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog;
			this->MaximizeBox = false;
			this->MinimizeBox = false;
			this->Name = L"MainForm";
			this->ShowIcon = false;
			this->Text = L"MySQL++ Windows Forms Examples";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
};
}
Deleted examples/vstudio/wforms/MainForm.resX.
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




































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="label3.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
  <metadata name="label4.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>False</value>
  </metadata>
</root>
Deleted examples/vstudio/wforms/resource.h.
1
2
3



-
-
-
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by app.rc
Deleted examples/vstudio/wforms/wforms.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
// wforms.cpp : main project file.

#include "MainForm.h"

using namespace wforms;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	// Create the main window and run it
	Application::Run(gcnew MainForm());
	return 0;
}
Deleted examples/xaction.cpp.
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














































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 xaction.cpp - Example showing how to use the transaction support in
 	MySQL++ v2.1 and up.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "stock.h"
#include "util.h"

#include <transaction.h>

#include <iostream>

using namespace std;

int
main(int argc, char *argv[])
{
	try {
		// Establish the connection to the database server.
		mysqlpp::Connection con(mysqlpp::use_exceptions);
		if (!connect_to_db(argc, argv, con)) {
			return 1;
		}

		// Show initial state
		mysqlpp::Query query = con.query();
		cout << "Initial state of stock table:" << endl;
		print_stock_table(query);

		// Insert a few rows in a single transaction set
		{
			mysqlpp::Transaction trans(con);

			stock row1("Sauerkraut", 42, 1.2, 0.75, "2006-03-06");
			query.insert(row1);
			query.execute();
			query.reset();

			stock row2("Bratwurst", 24, 3.0, 4.99, "2006-03-06");
			query.insert(row2);
			query.execute();
			query.reset();

			cout << "\nRows are inserted, but not committed." << endl;
			cout << "Verify this with another program (e.g. simple1), "
					"then hit Enter." << endl;
			getchar();

			cout << "\nCommitting transaction gives us:" << endl;
			trans.commit();
			print_stock_table(query);
		}
			
		// Now let's test auto-rollback
		{
			mysqlpp::Transaction trans(con);
			cout << "\nNow adding catsup to the database..." << endl;

			stock row("Catsup", 3, 3.9, 2.99, "2006-03-06");
			query.insert(row);
			query.execute();
			query.reset();
		}
		cout << "\nNo, yuck! We don't like catsup. Rolling it back:" <<
				endl;
		print_stock_table(query);
			
	}
	catch (const mysqlpp::BadQuery& er) {
		// Handle any query errors
		cerr << "Query error: " << er.what() << endl;
		return -1;
	}
	catch (const mysqlpp::BadConversion& er) {	
		// Handle bad conversions
		cerr << "Conversion error: " << er.what() << endl <<
				"\tretrieved data size: " << er.retrieved <<
				", actual size: " << er.actual_size << endl;
		return -1;
	}
	catch (const mysqlpp::Exception& er) {
		// Catch-all for any other MySQL++ exceptions
		cerr << "Error: " << er.what() << endl;
		return -1;
	}

	return 0;
}
Deleted exrun.
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






















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/bin/sh
if [ -z "$1" ]
then
	echo "usage: $0 <example> [args...]"
	echo
	echo "   Runs the given example, using the library in the current directory"
	echo "   instead of using the system library search mechanism.  Accepts an "
	echo "   arbitrary number of arguments."
	echo
	echo "   Example can be 'valgrind' instead, in which case we run the example"
	echo "   under valgrind in memory checking mode."
	echo
	exit 1
fi

TOOL=
PROG=$1
if [ "$PROG" == 'valgrind' ]
then
	TOOL='valgrind'
	shift
	PROG=$1
elif [ "$PROG" == 'gdb' ]
then
	TOOL='gdb --args'
	shift
	PROG=$1
fi

if [ -n "$1" ]
then
	shift

	if [ ! -e libmysqlpp.so.2 ]
	then
		( ln -sf libmysqlpp.so libmysqlpp.so.2 )
	fi

	if [ -e /usr/bin/ldd ]
	then
		LD_LIBRARY_PATH=. $TOOL ./$PROG $*
	elif [ -e /usr/bin/otool ]
	then
		DYLD_LIBRARY_PATH=. $TOOL ./$PROG $*
	else
		echo ERROR: I don\'t grok this system\'s dynamic linkage system.
	fi
else
	echo "usage: $0 $TOOL <example> [args...]"
	echo
	echo "   Run $0 without arguments for more detailed usage info."
	echo
	exit 1
fi
Deleted exrun.bat.
1
2
3
4
5
6
7







-
-
-
-
-
-
-
@echo off
set PROG=%1
if not exist %PROG% set PROG=Debug\%1
shift

set PATH=Debug;%PATH%
%PROG% %*
Deleted install.bat.
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






































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@echo off
if "%1" == "" goto error

set BASE_DIR=c:\mysql++
set INST_INC_DIR=%BASE_DIR%\include
set INST_LIB_DIR=%BASE_DIR%\%1

if not exist %BASE_DIR% mkdir %BASE_DIR%
if not exist %INST_INC_DIR% mkdir %INST_INC_DIR%
if not exist %INST_LIB_DIR% mkdir %INST_LIB_DIR%
if not exist %INST_LIB_DIR%\debug mkdir %INST_LIB_DIR%\debug
if not exist %INST_LIB_DIR%\release mkdir %INST_LIB_DIR%\release

copy lib\*.h "%INST_INC_DIR%" > NUL

if exist *.a goto install_mingw
copy debug\*.dll "%INST_LIB_DIR%\debug" > NUL
copy debug\*.lib "%INST_LIB_DIR%\debug" > NUL
copy release\*.dll "%INST_LIB_DIR%\release" > NUL
copy release\*.lib "%INST_LIB_DIR%\release" > NUL
goto install_done
:install_mingw
copy *.a "%INST_LIB_DIR%\debug" > NUL
echo WARNING: I assume you built a debug version of the library, as that
echo is what you get with MinGW unless you make a special effort.  You
echo must do a manual install if you make a release version.

:install_done
echo MySQL++ (%1 version) installed successfully!
goto end

:error
echo usage: install [subdir]
echo.
echo 	Installs MySQL++ into the given subdirectory of %BASE_DIR%

:end

Deleted lib/Doxyfile.in.
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










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# Doxyfile 1.5.2-1

# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
#       TAG = value [value, ...]
# For lists items can also be appended using:
#       TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------

# This tag specifies the encoding used for all characters in the config file that 
# follow. The default is UTF-8 which is also the encoding used for all text before 
# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
# possible encodings.

DOXYFILE_ENCODING      = UTF-8

# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
# by quotes) that should identify the project.

PROJECT_NAME           = MySQL++

# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
# This could be handy for archiving the generated documentation or 
# if some version control system is used.

PROJECT_NUMBER         = @PACKAGE_VERSION@

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
# base path where the generated documentation will be put. 
# If a relative path is entered, it will be relative to the location 
# where doxygen was started. If left blank the current directory will be used.

OUTPUT_DIRECTORY       = ../doc

# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
# 4096 sub-directories (in 2 levels) under the output directory of each output 
# format and will distribute the generated files over these directories. 
# Enabling this option can be useful when feeding doxygen a huge amount of 
# source files, where putting all generated files in the same directory would 
# otherwise cause performance problems for the file system.

CREATE_SUBDIRS         = NO

# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
# documentation generated by doxygen is written. Doxygen will use this 
# information to generate all constant output in the proper language. 
# The default language is English, other supported languages are: 
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.

OUTPUT_LANGUAGE        = English

# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
# include brief member descriptions after the members that are listed in 
# the file and class documentation (similar to JavaDoc). 
# Set to NO to disable this.

BRIEF_MEMBER_DESC      = YES

# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
# the brief description of a member or function before the detailed description. 
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
# brief descriptions will be completely suppressed.

REPEAT_BRIEF           = YES

# This tag implements a quasi-intelligent brief description abbreviator 
# that is used to form the text in various listings. Each string 
# in this list, if found as the leading text of the brief description, will be 
# stripped from the text and the result after processing the whole list, is 
# used as the annotated text. Otherwise, the brief description is used as-is. 
# If left blank, the following values are used ("$name" is automatically 
# replaced with the name of the entity): "The $name class" "The $name widget" 
# "The $name file" "is" "provides" "specifies" "contains" 
# "represents" "a" "an" "the"

ABBREVIATE_BRIEF       = 

# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
# Doxygen will generate a detailed section even if there is only a brief 
# description.

ALWAYS_DETAILED_SEC    = NO

# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
# inherited members of a class in the documentation of that class as if those 
# members were ordinary class members. Constructors, destructors and assignment 
# operators of the base classes will not be shown.

INLINE_INHERITED_MEMB  = NO

# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
# path before files name in the file list and in the header files. If set 
# to NO the shortest path that makes the file name unique will be used.

FULL_PATH_NAMES        = NO

# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
# can be used to strip a user-defined part of the path. Stripping is 
# only done if one of the specified strings matches the left-hand part of 
# the path. The tag can be used to show relative paths in the file list. 
# If left blank the directory from which doxygen is run is used as the 
# path to strip.

STRIP_FROM_PATH        = 

# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
# the path mentioned in the documentation of a class, which tells 
# the reader which header file to include in order to use a class. 
# If left blank only the name of the header file containing the class 
# definition is used. Otherwise one should specify the include paths that 
# are normally passed to the compiler using the -I flag.

STRIP_FROM_INC_PATH    = 

# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
# (but less readable) file names. This can be useful is your file systems 
# doesn't support long names like on DOS, Mac, or CD-ROM.

SHORT_NAMES            = NO

# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
# will interpret the first line (until the first dot) of a JavaDoc-style 
# comment as the brief description. If set to NO, the JavaDoc 
# comments will behave just like the Qt-style comments (thus requiring an 
# explicit @brief command for a brief description.

JAVADOC_AUTOBRIEF      = NO

# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
# comments) as a brief description. This used to be the default behaviour. 
# The new default is to treat a multi-line C++ comment block as a detailed 
# description. Set this tag to YES if you prefer the old behaviour instead.

MULTILINE_CPP_IS_BRIEF = NO

# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
# will output the detailed description near the top, like JavaDoc.
# If set to NO, the detailed description appears after the member 
# documentation.

DETAILS_AT_TOP         = NO

# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
# member inherits the documentation from any documented member that it 
# re-implements.

INHERIT_DOCS           = YES

# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
# a new page for each member. If set to NO, the documentation of a member will 
# be part of the file/class/namespace that contains it.

SEPARATE_MEMBER_PAGES  = NO

# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
# Doxygen uses this value to replace tabs by spaces in code fragments.

TAB_SIZE               = 8

# This tag can be used to specify a number of aliases that acts 
# as commands in the documentation. An alias has the form "name=value". 
# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
# put the command \sideeffect (or @sideeffect) in the documentation, which 
# will result in a user-defined paragraph with heading "Side Effects:". 
# You can put \n's in the value part of an alias to insert newlines.

ALIASES                = 

# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
# sources only. Doxygen will then generate output that is more tailored for C. 
# For instance, some of the names that are used will be different. The list 
# of all members will be omitted, etc.

OPTIMIZE_OUTPUT_FOR_C  = NO

# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
# sources only. Doxygen will then generate output that is more tailored for Java. 
# For instance, namespaces will be presented as packages, qualified scopes 
# will look different, etc.

OPTIMIZE_OUTPUT_JAVA   = NO

# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
# include (a tag file for) the STL sources as input, then you should 
# set this tag to YES in order to let doxygen match functions declarations and 
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
# func(std::string) {}). This also make the inheritance and collaboration 
# diagrams that involve STL classes more complete and accurate.

BUILTIN_STL_SUPPORT    = YES

# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.

CPP_CLI_SUPPORT        = NO

# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
# tag is set to YES, then doxygen will reuse the documentation of the first 
# member in the group (if any) for the other members of the group. By default 
# all members of a group must be documented explicitly.

DISTRIBUTE_GROUP_DOC   = NO

# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
# the same type (for instance a group of public functions) to be put as a 
# subgroup of that type (e.g. under the Public Functions section). Set it to 
# NO to prevent subgrouping. Alternatively, this can be done per class using 
# the \nosubgrouping command.

SUBGROUPING            = YES

#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------

# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
# documentation are documented, even if no documentation was available. 
# Private class members and static file members will be hidden unless 
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES

EXTRACT_ALL            = NO

# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
# will be included in the documentation.

EXTRACT_PRIVATE        = NO

# If the EXTRACT_STATIC tag is set to YES all static members of a file 
# will be included in the documentation.

EXTRACT_STATIC         = NO

# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
# defined locally in source files will be included in the documentation. 
# If set to NO only classes defined in header files are included.

EXTRACT_LOCAL_CLASSES  = YES

# This flag is only useful for Objective-C code. When set to YES local 
# methods, which are defined in the implementation section but not in 
# the interface are included in the documentation. 
# If set to NO (the default) only methods in the interface are included.

EXTRACT_LOCAL_METHODS  = NO

# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
# undocumented members of documented classes, files or namespaces. 
# If set to NO (the default) these members will be included in the 
# various overviews, but no documentation section is generated. 
# This option has no effect if EXTRACT_ALL is enabled.

HIDE_UNDOC_MEMBERS     = NO

# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
# undocumented classes that are normally visible in the class hierarchy. 
# If set to NO (the default) these classes will be included in the various 
# overviews. This option has no effect if EXTRACT_ALL is enabled.

HIDE_UNDOC_CLASSES     = NO

# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
# friend (class|struct|union) declarations. 
# If set to NO (the default) these declarations will be included in the 
# documentation.

HIDE_FRIEND_COMPOUNDS  = NO

# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
# documentation blocks found inside the body of a function. 
# If set to NO (the default) these blocks will be appended to the 
# function's detailed documentation block.

HIDE_IN_BODY_DOCS      = NO

# The INTERNAL_DOCS tag determines if documentation 
# that is typed after a \internal command is included. If the tag is set 
# to NO (the default) then the documentation will be excluded. 
# Set it to YES to include the internal documentation.

INTERNAL_DOCS          = NO

# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
# file names in lower-case letters. If set to YES upper-case letters are also 
# allowed. This is useful if you have classes or files whose names only differ 
# in case and if your file system supports case sensitive file names. Windows 
# and Mac users are advised to set this option to NO.

CASE_SENSE_NAMES       = YES

# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
# will show members with their full class and namespace scopes in the 
# documentation. If set to YES the scope will be hidden.

HIDE_SCOPE_NAMES       = NO

# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
# will put a list of the files that are included by a file in the documentation 
# of that file.

SHOW_INCLUDE_FILES     = YES

# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
# is inserted in the documentation for inline members.

INLINE_INFO            = YES

# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
# will sort the (detailed) documentation of file and class members 
# alphabetically by member name. If set to NO the members will appear in 
# declaration order.

SORT_MEMBER_DOCS       = YES

# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
# brief documentation of file, namespace and class members alphabetically 
# by member name. If set to NO (the default) the members will appear in 
# declaration order.

SORT_BRIEF_DOCS        = NO

# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
# sorted by fully-qualified names, including namespaces. If set to 
# NO (the default), the class list will be sorted only by class name, 
# not including the namespace part. 
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the 
# alphabetical list.

SORT_BY_SCOPE_NAME     = NO

# The GENERATE_TODOLIST tag can be used to enable (YES) or 
# disable (NO) the todo list. This list is created by putting \todo 
# commands in the documentation.

GENERATE_TODOLIST      = YES

# The GENERATE_TESTLIST tag can be used to enable (YES) or 
# disable (NO) the test list. This list is created by putting \test 
# commands in the documentation.

GENERATE_TESTLIST      = YES

# The GENERATE_BUGLIST tag can be used to enable (YES) or 
# disable (NO) the bug list. This list is created by putting \bug 
# commands in the documentation.

GENERATE_BUGLIST       = YES

# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
# disable (NO) the deprecated list. This list is created by putting 
# \deprecated commands in the documentation.

GENERATE_DEPRECATEDLIST= YES

# The ENABLED_SECTIONS tag can be used to enable conditional 
# documentation sections, marked by \if sectionname ... \endif.

ENABLED_SECTIONS       = 

# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
# the initial value of a variable or define consists of for it to appear in 
# the documentation. If the initializer consists of more lines than specified 
# here it will be hidden. Use a value of 0 to hide initializers completely. 
# The appearance of the initializer of individual variables and defines in the 
# documentation can be controlled using \showinitializer or \hideinitializer 
# command in the documentation regardless of this setting.

MAX_INITIALIZER_LINES  = 30

# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
# at the bottom of the documentation of classes and structs. If set to YES the 
# list will mention the files that were used to generate the documentation.

SHOW_USED_FILES        = YES

# If the sources in your project are distributed over multiple directories 
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
# in the documentation. The default is NO.

SHOW_DIRECTORIES       = NO

# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
# doxygen should invoke to get the current version for each file (typically from the 
# version control system). Doxygen will invoke the program by executing (via 
# popen()) the command <command> <input-file>, where <command> is the value of 
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
# provided by doxygen. Whatever the program writes to standard output 
# is used as the file version. See the manual for examples.

FILE_VERSION_FILTER    = 

#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------

# The QUIET tag can be used to turn on/off the messages that are generated 
# by doxygen. Possible values are YES and NO. If left blank NO is used.

QUIET                  = NO

# The WARNINGS tag can be used to turn on/off the warning messages that are 
# generated by doxygen. Possible values are YES and NO. If left blank 
# NO is used.

WARNINGS               = YES

# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
# automatically be disabled.

WARN_IF_UNDOCUMENTED   = YES

# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
# potential errors in the documentation, such as not documenting some 
# parameters in a documented function, or documenting parameters that 
# don't exist or using markup commands wrongly.

WARN_IF_DOC_ERROR      = YES

# This WARN_NO_PARAMDOC option can be abled to get warnings for 
# functions that are documented, but have no documentation for their parameters 
# or return value. If set to NO (the default) doxygen will only warn about 
# wrong or incomplete parameter documentation, but not about the absence of 
# documentation.

WARN_NO_PARAMDOC       = NO

# The WARN_FORMAT tag determines the format of the warning messages that 
# doxygen can produce. The string should contain the $file, $line, and $text 
# tags, which will be replaced by the file and line number from which the 
# warning originated and the warning text. Optionally the format may contain 
# $version, which will be replaced by the version of the file (if it could 
# be obtained via FILE_VERSION_FILTER)

WARN_FORMAT            = "$file:$line: $text"

# The WARN_LOGFILE tag can be used to specify a file to which warning 
# and error messages should be written. If left blank the output is written 
# to stderr.

WARN_LOGFILE           = 

#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------

# The INPUT tag can be used to specify the files and/or directories that contain 
# documented source files. You may enter file names like "myfile.cpp" or 
# directories like "/usr/src/myproject". Separate the files or directories 
# with spaces.

INPUT                  = 

# This tag can be used to specify the character encoding of the source files that 
# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
# See http://www.gnu.org/software/libiconv for the list of possible encodings.

INPUT_ENCODING         = UTF-8

# If the value of the INPUT tag contains directories, you can use the 
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
# and *.h) to filter out the source-files in the directories. If left 
# blank the following patterns are tested: 
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py

FILE_PATTERNS          = 

# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
# should be searched for input files as well. Possible values are YES and NO. 
# If left blank NO is used.

RECURSIVE              = NO

# The EXCLUDE tag can be used to specify files and/or directories that should 
# excluded from the INPUT source files. This way you can easily exclude a 
# subdirectory from a directory tree whose root is specified with the INPUT tag.

EXCLUDE                = custom.h \
                         custom-macros.h

# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
# directories that are symbolic links (a Unix filesystem feature) are excluded 
# from the input.

EXCLUDE_SYMLINKS       = NO

# If the value of the INPUT tag contains directories, you can use the 
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
# certain files from those directories. Note that the wildcards are matched 
# against the file with absolute path, so to exclude all test directories 
# for example use the pattern */test/*

EXCLUDE_PATTERNS       = 

# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
# (namespaces, classes, functions, etc.) that should be excluded from the output. 
# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test

EXCLUDE_SYMBOLS        = 

# The EXAMPLE_PATH tag can be used to specify one or more files or 
# directories that contain example code fragments that are included (see 
# the \include command).

EXAMPLE_PATH           = 

# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
# and *.h) to filter out the source-files in the directories. If left 
# blank all files are included.

EXAMPLE_PATTERNS       = 

# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
# searched for input files to be used with the \include or \dontinclude 
# commands irrespective of the value of the RECURSIVE tag. 
# Possible values are YES and NO. If left blank NO is used.

EXAMPLE_RECURSIVE      = NO

# The IMAGE_PATH tag can be used to specify one or more files or 
# directories that contain image that are included in the documentation (see 
# the \image command).

IMAGE_PATH             = 

# The INPUT_FILTER tag can be used to specify a program that doxygen should 
# invoke to filter for each input file. Doxygen will invoke the filter program 
# by executing (via popen()) the command <filter> <input-file>, where <filter> 
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
# input file. Doxygen will then use the output that the filter program writes 
# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
# ignored.

INPUT_FILTER           = 

# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
# basis.  Doxygen will compare the file name with each pattern and apply the 
# filter if there is a match.  The filters are a list of the form: 
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
# is applied to all files.

FILTER_PATTERNS        = 

# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
# INPUT_FILTER) will be used to filter the input files when producing source 
# files to browse (i.e. when SOURCE_BROWSER is set to YES).

FILTER_SOURCE_FILES    = NO

#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------

# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
# be generated. Documented entities will be cross-referenced with these sources. 
# Note: To get rid of all source code in the generated output, make sure also 
# VERBATIM_HEADERS is set to NO.

SOURCE_BROWSER         = NO

# Setting the INLINE_SOURCES tag to YES will include the body 
# of functions and classes directly in the documentation.

INLINE_SOURCES         = NO

# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
# doxygen to hide any special comment blocks from generated source code 
# fragments. Normal C and C++ comments will always remain visible.

STRIP_CODE_COMMENTS    = YES

# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
# then for each documented function all documented 
# functions referencing it will be listed.

REFERENCED_BY_RELATION = YES

# If the REFERENCES_RELATION tag is set to YES (the default) 
# then for each documented function all documented entities 
# called/used by that function will be listed.

REFERENCES_RELATION    = YES

# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
# link to the source code.  Otherwise they will link to the documentstion.

REFERENCES_LINK_SOURCE = YES

# If the USE_HTAGS tag is set to YES then the references to source code 
# will point to the HTML generated by the htags(1) tool instead of doxygen 
# built-in source browser. The htags tool is part of GNU's global source 
# tagging system (see http://www.gnu.org/software/global/global.html). You 
# will need version 4.8.6 or higher.

USE_HTAGS              = NO

# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
# will generate a verbatim copy of the header file for each class for 
# which an include is specified. Set to NO to disable this.

VERBATIM_HEADERS       = YES

#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------

# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
# of all compounds will be generated. Enable this if the project 
# contains a lot of classes, structs, unions or interfaces.

ALPHABETICAL_INDEX     = NO

# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
# in which this list will be split (can be a number in the range [1..20])

COLS_IN_ALPHA_INDEX    = 5

# In case all classes in a project start with a common prefix, all 
# classes will be put under the same header in the alphabetical index. 
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
# should be ignored while generating the index headers.

IGNORE_PREFIX          = 

#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------

# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
# generate HTML output.

GENERATE_HTML          = YES

# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
# put in front of it. If left blank `html' will be used as the default path.

HTML_OUTPUT            = html/refman

# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
# doxygen will generate files with .html extension.

HTML_FILE_EXTENSION    = .html

# The HTML_HEADER tag can be used to specify a personal HTML header for 
# each generated HTML page. If it is left blank doxygen will generate a 
# standard header.

HTML_HEADER            = ../doc/html/refman/_header.html

# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
# each generated HTML page. If it is left blank doxygen will generate a 
# standard footer.

HTML_FOOTER            = 

# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
# style sheet that is used by each HTML page. It can be used to 
# fine-tune the look of the HTML output. If the tag is left blank doxygen 
# will generate a default style sheet. Note that doxygen will try to copy 
# the style sheet file to the HTML output directory, so don't put your own 
# stylesheet in the HTML output directory as well, or it will be erased!

HTML_STYLESHEET        = 

# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
# files or namespaces will be aligned in HTML using tables. If set to 
# NO a bullet list will be used.

HTML_ALIGN_MEMBERS     = YES

# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
# will be generated that can be used as input for tools like the 
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
# of the generated HTML documentation.

GENERATE_HTMLHELP      = NO

# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
# be used to specify the file name of the resulting .chm file. You 
# can add a path in front of the file if the result should not be 
# written to the html output directory.

CHM_FILE               = 

# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
# be used to specify the location (absolute path including file name) of 
# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
# the HTML help compiler on the generated index.hhp.

HHC_LOCATION           = 

# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
# controls if a separate .chi index file is generated (YES) or that 
# it should be included in the master .chm file (NO).

GENERATE_CHI           = NO

# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
# controls whether a binary table of contents is generated (YES) or a 
# normal table of contents (NO) in the .chm file.

BINARY_TOC             = NO

# The TOC_EXPAND flag can be set to YES to add extra items for group members 
# to the contents of the HTML help documentation and to the tree view.

TOC_EXPAND             = NO

# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
# top of each HTML page. The value NO (the default) enables the index and 
# the value YES disables it.

DISABLE_INDEX          = NO

# This tag can be used to set the number of enum values (range [1..20]) 
# that doxygen will group on one line in the generated HTML documentation.

ENUM_VALUES_PER_LINE   = 4

# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that 
# is generated for HTML Help). For this to work a browser that supports 
# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
# probably better off using the HTML help feature.

GENERATE_TREEVIEW      = NO

# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
# used to set the initial width (in pixels) of the frame in which the tree 
# is shown.

TREEVIEW_WIDTH         = 250

#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------

# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
# generate Latex output.

GENERATE_LATEX         = YES

# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
# put in front of it. If left blank `latex' will be used as the default path.

LATEX_OUTPUT           = latex

# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
# invoked. If left blank `latex' will be used as the default command name.

LATEX_CMD_NAME         = latex

# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
# generate index for LaTeX. If left blank `makeindex' will be used as the 
# default command name.

MAKEINDEX_CMD_NAME     = makeindex

# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
# LaTeX documents. This may be useful for small projects and may help to 
# save some trees in general.

COMPACT_LATEX          = NO

# The PAPER_TYPE tag can be used to set the paper type that is used 
# by the printer. Possible values are: a4, a4wide, letter, legal and 
# executive. If left blank a4wide will be used.

PAPER_TYPE             = letter

# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
# packages that should be included in the LaTeX output.

EXTRA_PACKAGES         = 

# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
# the generated latex document. The header should contain everything until 
# the first chapter. If it is left blank doxygen will generate a 
# standard header. Notice: only use this tag if you know what you are doing!

LATEX_HEADER           = 

# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
# contain links (just like the HTML output) instead of page references 
# This makes the output suitable for online browsing using a pdf viewer.

PDF_HYPERLINKS         = NO

# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
# plain latex in the generated Makefile. Set this option to YES to get a 
# higher quality PDF documentation.

USE_PDFLATEX           = YES

# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
# command to the generated LaTeX files. This will instruct LaTeX to keep 
# running if errors occur, instead of asking the user for help. 
# This option is also used when generating formulas in HTML.

LATEX_BATCHMODE        = NO

# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
# include the index chapters (such as File Index, Compound Index, etc.) 
# in the output.

LATEX_HIDE_INDICES     = NO

#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------

# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
# The RTF output is optimized for Word 97 and may not look very pretty with 
# other RTF readers or editors.

GENERATE_RTF           = NO

# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
# put in front of it. If left blank `rtf' will be used as the default path.

RTF_OUTPUT             = rtf

# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
# RTF documents. This may be useful for small projects and may help to 
# save some trees in general.

COMPACT_RTF            = NO

# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
# will contain hyperlink fields. The RTF file will 
# contain links (just like the HTML output) instead of page references. 
# This makes the output suitable for online browsing using WORD or other 
# programs which support those fields. 
# Note: wordpad (write) and others do not support links.

RTF_HYPERLINKS         = NO

# Load stylesheet definitions from file. Syntax is similar to doxygen's 
# config file, i.e. a series of assignments. You only have to provide 
# replacements, missing definitions are set to their default value.

RTF_STYLESHEET_FILE    = 

# Set optional variables used in the generation of an rtf document. 
# Syntax is similar to doxygen's config file.

RTF_EXTENSIONS_FILE    = 

#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------

# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
# generate man pages

GENERATE_MAN           = NO

# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
# put in front of it. If left blank `man' will be used as the default path.

MAN_OUTPUT             = man

# The MAN_EXTENSION tag determines the extension that is added to 
# the generated man pages (default is the subroutine's section .3)

MAN_EXTENSION          = .3

# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
# then it will generate one additional man file for each entity 
# documented in the real man page(s). These additional files 
# only source the real man page, but without them the man command 
# would be unable to find the correct page. The default is NO.

MAN_LINKS              = NO

#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------

# If the GENERATE_XML tag is set to YES Doxygen will 
# generate an XML file that captures the structure of 
# the code including all documentation.

GENERATE_XML           = NO

# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
# put in front of it. If left blank `xml' will be used as the default path.

XML_OUTPUT             = xml

# The XML_SCHEMA tag can be used to specify an XML schema, 
# which can be used by a validating XML parser to check the 
# syntax of the XML files.

XML_SCHEMA             = 

# The XML_DTD tag can be used to specify an XML DTD, 
# which can be used by a validating XML parser to check the 
# syntax of the XML files.

XML_DTD                = 

# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
# dump the program listings (including syntax highlighting 
# and cross-referencing information) to the XML output. Note that 
# enabling this will significantly increase the size of the XML output.

XML_PROGRAMLISTING     = YES

#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------

# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
# generate an AutoGen Definitions (see autogen.sf.net) file 
# that captures the structure of the code including all 
# documentation. Note that this feature is still experimental 
# and incomplete at the moment.

GENERATE_AUTOGEN_DEF   = NO

#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------

# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
# generate a Perl module file that captures the structure of 
# the code including all documentation. Note that this 
# feature is still experimental and incomplete at the 
# moment.

GENERATE_PERLMOD       = NO

# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
# to generate PDF and DVI output from the Perl module output.

PERLMOD_LATEX          = NO

# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
# nicely formatted so it can be parsed by a human reader.  This is useful 
# if you want to understand what is going on.  On the other hand, if this 
# tag is set to NO the size of the Perl module output will be much smaller 
# and Perl will parse it just the same.

PERLMOD_PRETTY         = YES

# The names of the make variables in the generated doxyrules.make file 
# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
# This is useful so different doxyrules.make files included by the same 
# Makefile don't overwrite each other's variables.

PERLMOD_MAKEVAR_PREFIX = 

#---------------------------------------------------------------------------
# Configuration options related to the preprocessor   
#---------------------------------------------------------------------------

# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
# evaluate all C-preprocessor directives found in the sources and include 
# files.

ENABLE_PREPROCESSING   = YES

# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
# names in the source code. If set to NO (the default) only conditional 
# compilation will be performed. Macro expansion can be done in a controlled 
# way by setting EXPAND_ONLY_PREDEF to YES.

MACRO_EXPANSION        = NO

# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
# then the macro expansion is limited to the macros specified with the 
# PREDEFINED and EXPAND_AS_DEFINED tags.

EXPAND_ONLY_PREDEF     = NO

# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
# in the INCLUDE_PATH (see below) will be search if a #include is found.

SEARCH_INCLUDES        = YES

# The INCLUDE_PATH tag can be used to specify one or more directories that 
# contain include files that are not input files but should be processed by 
# the preprocessor.

INCLUDE_PATH           = 

# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
# patterns (like *.h and *.hpp) to filter out the header-files in the 
# directories. If left blank, the patterns specified with FILE_PATTERNS will 
# be used.

INCLUDE_FILE_PATTERNS  = 

# The PREDEFINED tag can be used to specify one or more macro names that 
# are defined before the preprocessor is started (similar to the -D option of 
# gcc). The argument of the tag is a list of macros of the form: name 
# or name=definition (no spaces). If the definition and the = are 
# omitted =1 is assumed. To prevent a macro definition from being 
# undefined via #undef or recursively expanded use the := operator 
# instead of the = operator.

PREDEFINED             = DOXYGEN_IGNORE

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
# this tag can be used to specify a list of macro names that should be expanded. 
# The macro definition that is found in the sources will be used. 
# Use the PREDEFINED tag if you want to use a different macro definition.

EXPAND_AS_DEFINED      = 

# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
# doxygen's preprocessor will remove all function-like macros that are alone 
# on a line, have an all uppercase name, and do not end with a semicolon. Such 
# function macros are typically used for boiler-plate code, and will confuse 
# the parser if not removed.

SKIP_FUNCTION_MACROS   = YES

#---------------------------------------------------------------------------
# Configuration::additions related to external references   
#---------------------------------------------------------------------------

# The TAGFILES option can be used to specify one or more tagfiles. 
# Optionally an initial location of the external documentation 
# can be added for each tagfile. The format of a tag file without 
# this location is as follows: 
#   TAGFILES = file1 file2 ... 
# Adding location for the tag files is done as follows: 
#   TAGFILES = file1=loc1 "file2 = loc2" ... 
# where "loc1" and "loc2" can be relative or absolute paths or 
# URLs. If a location is present for each tag, the installdox tool 
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
# If a tag file is not located in the directory in which doxygen 
# is run, you must also specify the path to the tagfile here.

TAGFILES               = 

# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
# a tag file that is based on the input files it reads.

GENERATE_TAGFILE       = 

# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
# in the class index. If set to NO only the inherited external classes 
# will be listed.

ALLEXTERNALS           = NO

# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
# in the modules index. If set to NO, only the current project's groups will 
# be listed.

EXTERNAL_GROUPS        = YES

# The PERL_PATH should be the absolute path and name of the perl script 
# interpreter (i.e. the result of `which perl').

PERL_PATH              = /usr/bin/perl

#---------------------------------------------------------------------------
# Configuration options related to the dot tool   
#---------------------------------------------------------------------------

# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
# or super classes. Setting the tag to NO turns the diagrams off. Note that 
# this option is superseded by the HAVE_DOT option below. This is only a 
# fallback. It is recommended to install and use dot, since it yields more 
# powerful graphs.

CLASS_DIAGRAMS         = YES

# You can define message sequence charts within doxygen comments using the \msc 
# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
# be found in the default search path.

MSCGEN_PATH            = 

# If set to YES, the inheritance and collaboration graphs will hide 
# inheritance and usage relations if the target is undocumented 
# or is not a class.

HIDE_UNDOC_RELATIONS   = YES

# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
# available from the path. This tool is part of Graphviz, a graph visualization 
# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
# have no effect if this option is set to NO (the default)

HAVE_DOT               = YES

# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
# will generate a graph for each documented class showing the direct and 
# indirect inheritance relations. Setting this tag to YES will force the 
# the CLASS_DIAGRAMS tag to NO.

CLASS_GRAPH            = YES

# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
# will generate a graph for each documented class showing the direct and 
# indirect implementation dependencies (inheritance, containment, and 
# class references variables) of the class with other documented classes.

COLLABORATION_GRAPH    = YES

# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
# will generate a graph for groups, showing the direct groups dependencies

GROUP_GRAPHS           = YES

# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
# collaboration diagrams in a style similar to the OMG's Unified Modeling 
# Language.

UML_LOOK               = NO

# If set to YES, the inheritance and collaboration graphs will show the 
# relations between templates and their instances.

TEMPLATE_RELATIONS     = YES

# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
# tags are set to YES then doxygen will generate a graph for each documented 
# file showing the direct and indirect include dependencies of the file with 
# other documented files.

INCLUDE_GRAPH          = YES

# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
# documented header file showing the documented files that directly or 
# indirectly include this file.

INCLUDED_BY_GRAPH      = YES

# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
# generate a call dependency graph for every global function or class method. 
# Note that enabling this option will significantly increase the time of a run. 
# So in most cases it will be better to enable call graphs for selected 
# functions only using the \callgraph command.

CALL_GRAPH             = NO

# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
# generate a caller dependency graph for every global function or class method. 
# Note that enabling this option will significantly increase the time of a run. 
# So in most cases it will be better to enable caller graphs for selected 
# functions only using the \callergraph command.

CALLER_GRAPH           = NO

# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
# will graphical hierarchy of all classes instead of a textual one.

GRAPHICAL_HIERARCHY    = YES

# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
# then doxygen will show the dependencies a directory has on other directories 
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.

DIRECTORY_GRAPH        = YES

# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
# generated by dot. Possible values are png, jpg, or gif
# If left blank png will be used.

DOT_IMAGE_FORMAT       = png

# The tag DOT_PATH can be used to specify the path where the dot tool can be 
# found. If left blank, it is assumed the dot tool can be found in the path.

DOT_PATH               = 

# The DOTFILE_DIRS tag can be used to specify one or more directories that 
# contain dot files that are included in the documentation (see the 
# \dotfile command).

DOTFILE_DIRS           = 

# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
# nodes that will be shown in the graph. If the number of nodes in a graph 
# becomes larger than this value, doxygen will truncate the graph, which is 
# visualized by representing a node as a red box. Note that doxygen will always 
# show the root nodes and its direct children regardless of this setting.

DOT_GRAPH_MAX_NODES    = 50

# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
# background. This is disabled by default, which results in a white background. 
# Warning: Depending on the platform used, enabling this option may lead to 
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
# read).

DOT_TRANSPARENT        = NO

# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
# files in one run (i.e. multiple -o and -T options on the command line). This 
# makes dot run faster, but since only newer versions of dot (>1.8.10) 
# support this, this feature is disabled by default.

DOT_MULTI_TARGETS      = NO

# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
# generate a legend page explaining the meaning of the various boxes and 
# arrows in the dot generated graphs.

GENERATE_LEGEND        = YES

# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
# remove the intermediate dot files that are used to generate 
# the various graphs.

DOT_CLEANUP            = YES

#---------------------------------------------------------------------------
# Configuration::additions related to the search engine   
#---------------------------------------------------------------------------

# The SEARCHENGINE tag specifies whether or not a search engine should be 
# used. If set to NO the values of all tags below this one will be ignored.

SEARCHENGINE           = NO
Deleted lib/autoflag.h.
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

























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file autoflag.h
/// \brief Defines a template for setting a flag within a given variable
/// scope, and resetting it when exiting that scope.

/***********************************************************************
 Copyright (c) 2007 by Educational Technology Resources, Inc.  Others
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#if !defined(MYSQLPP_AUTOFLAG_H)
#define MYSQLPP_AUTOFLAG_H

/// \brief A template for setting a flag on a variable as long as the
/// object that set it is in scope.  Flag resets when object goes
/// out of scope.  Works on anything that looks like bool.

template <class T = bool>
class AutoFlag
{
public:
	/// \brief Constructor: sets ref to true.
	AutoFlag(T& ref) :
	referent_(ref)
	{
		referent_ = true;
	}

	/// \brief Destructor: sets referent passed to ctor to false.
	~AutoFlag()
	{
		referent_ = false;
	}

private:
	T& referent_;
};

#endif // !defined(MYSQLPP_AUTOFLAG_H)

Deleted lib/coldata.cpp.
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





































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 coldata.cpp - Implements the ColData_Tmpl template.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "coldata.h"
#include "const_string.h"

#include <string>

namespace mysqlpp {

template class ColData_Tmpl<std::string>;
template class ColData_Tmpl<const_string>;

} // end namespace mysqlpp
Deleted lib/coldata.h.
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


































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file coldata.h
/// \brief Declares classes for converting string data to any of 
/// the basic C types.
///
/// Roughly speaking, this defines classes that are the inverse of
/// mysqlpp::SQLString.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_COLDATA_H
#define MYSQLPP_COLDATA_H

#include "common.h"

#include "const_string.h"
#include "convert.h"
#include "exceptions.h"
#include "null.h"
#include "string_util.h"
#include "type_info.h"

#include <typeinfo>
#include <string>
#include <sstream>

#include <stdlib.h>

namespace mysqlpp {

/// \brief Template for string data that can convert itself to any
/// standard C data type.
///
/// Do not use this class directly. Use the typedef ColData or
/// MutableColData instead. ColData is a \c ColData_Tmpl<const
/// \c std::string> and MutableColData is a
/// \c ColData_Tmpl<std::string>.
///
/// The ColData types add to the C++ string type the ability to
/// automatically convert the string data to any of the basic C types.
/// This is important with SQL, because all data coming from the
/// database is in string form.  MySQL++ uses this class internally
/// to hold the data it receives from the server, so you can use it
/// naturally, because it does the conversions implicitly:
///
/// \code ColData("12.86") + 2.0 \endcode
///
/// That works fine, but be careful.  If you had said this instead:
/// 
/// \code ColData("12.86") + 2 \endcode
/// 
/// the result would be 14 because 2 is an integer, and C++'s type
/// conversion rules put the ColData object in an integer context.
///
/// If these automatic conversions scare you, define the macro
/// NO_BINARY_OPERS to disable this behavior.
///
/// This class also has some basic information about the type of data
/// stored in it, to allow it to do the conversions more intelligently
/// than a trivial implementation would allow.

template <class Str>
class MYSQLPP_EXPORT ColData_Tmpl : public Str
{
public:
	/// \brief Default constructor
	///
	/// Null flag is set to false, type data is not set, and string
	/// data is left empty.
	///
	/// It's probably a bad idea to use this ctor, becuase there's no
	/// way to set the type data once the object's constructed.
	ColData_Tmpl() :
	null_(false)
	{
	}

	/// \brief Copy ctor
	///
	/// \param cd the other ColData_Tmpl object
	ColData_Tmpl(const ColData_Tmpl<Str>& cd) :
	Str(cd.data(), cd.length()),
	type_(cd.type_),
	null_(cd.null_)
	{
	}

	/// \brief Constructor allowing you to set the null flag and the
	/// type data.
	///
	/// \param n if true, data is a SQL null
	/// \param t MySQL type information for data being stored
	explicit ColData_Tmpl(bool n,
			mysql_type_info t = mysql_type_info::string_type) :
	type_(t),
	null_(n)
	{
	}

	/// \brief C++ string version of full ctor
	///
	/// \param str the string this object represents
	/// \param t MySQL type information for data within str
	/// \param n if true, str is a SQL null
	explicit ColData_Tmpl(const std::string& str,
			mysql_type_info t = mysql_type_info::string_type,
			bool n = false) :
	Str(str),
	type_(t),
	null_(n)
	{
	}

	/// \brief Null-terminated C string version of full ctor
	///
	/// \param str the string this object represents
	/// \param t MySQL type information for data within str
	/// \param n if true, str is a SQL null
	explicit ColData_Tmpl(const char* str,
			mysql_type_info t = mysql_type_info::string_type,
			bool n = false) :
	Str(str),
	type_(t),
	null_(n)
	{
	}

	/// \brief Full constructor.
	///
	/// \param str the string this object represents
	/// \param len the length of the string; embedded nulls are legal
	/// \param t MySQL type information for data within str
	/// \param n if true, str is a SQL null
	explicit ColData_Tmpl(const char* str, typename Str::size_type len,
			mysql_type_info t = mysql_type_info::string_type,
			bool n = false) :
	Str(str, len),
	type_(t),
	null_(n)
	{
	}

	/// \brief Get this object's current MySQL type.
	mysql_type_info type() const { return type_; }

	/// \brief Returns true if data of this type should be quoted, false
	/// otherwise.
	bool quote_q() const { return type_.quote_q(); }

	/// \brief Returns true if data of this type should be escaped, false
	/// otherwise.
	bool escape_q() const { return type_.escape_q(); }
	
	/// \brief Template for converting data from one type to another.
	template <class Type> Type conv(Type dummy) const;

	/// \brief Set a flag indicating that this object is a SQL null.
	void it_is_null() { null_ = true; }

	/// \brief Returns true if this object is a SQL null.
	inline const bool is_null() const { return null_; }
	
	/// \brief Returns this object's data in C++ string form.
	///
	/// This method is inefficient, and not recommended.  It makes a
	/// duplicate copy of the string that lives as long as the
	/// \c ColData object itself.
	///
	/// If you are using the \c MutableColData typedef for this
	/// template, you can avoid the duplicate copy entirely.  You can
	/// pass a \c MutableColData object to anything expecting a
	/// \c std::string and get the right result.  (This didn't work
	/// reliably prior to v2.3.)
	///
	/// This method is arguably useful with plain \c ColData objects,
	/// but there are more efficient alternatives.  If you know your
	/// data is a null-terminated C string, just cast this object to
	/// a \c const \c char* or call the \c data() method.  This gives
	/// you a pointer to our internal buffer, so the copy isn't needed.
	/// If the \c ColData can contain embedded null characters, you do
	/// need to make a copy, but it's better to make your own copy of 
	/// the string, instead of calling get_string(), so you can better
	/// control its lifetime:
	///
	/// \code
	/// ColData cd = ...;
	/// std::string s(cd.data(), cd.length());
	/// \endcode
	inline const std::string& get_string() const
	{
		temp_buf_.assign(Str::data(), Str::length());
		return temp_buf_;
	}

	/// \brief Returns a const char pointer to the object's raw data
	operator cchar*() const { return Str::data(); }
	
	/// \brief Converts this object's string data to a signed char
	operator signed char() const
			{ return conv(static_cast<signed char>(0)); }
	
	/// \brief Converts this object's string data to an unsigned char
	operator unsigned char() const
			{ return conv(static_cast<unsigned char>(0)); }
	
	/// \brief Converts this object's string data to an int
	operator int() const
			{ return conv(static_cast<int>(0)); }
	
	/// \brief Converts this object's string data to an unsigned int
	operator unsigned int() const
			{ return conv(static_cast<unsigned int>(0)); }
	
	/// \brief Converts this object's string data to a short int
	operator short int() const
			{ return conv(static_cast<short int>(0)); }
	
	/// \brief Converts this object's string data to an unsigned short
	/// int
	operator unsigned short int() const
			{ return conv(static_cast<unsigned short int>(0)); }
	
	/// \brief Converts this object's string data to a long int
	operator long int() const
			{ return conv(static_cast<long int>(0)); }
	
	/// \brief Converts this object's string data to an unsigned long
	/// int
	operator unsigned long int() const
			{ return conv(static_cast<unsigned long int>(0)); }
	
#if !defined(NO_LONG_LONGS)
	/// \brief Converts this object's string data to the platform-
	/// specific 'longlong' type, usually a 64-bit integer.
	operator longlong() const
			{ return conv(static_cast<longlong>(0)); }
	
	/// \brief Converts this object's string data to the platform-
	/// specific 'ulonglong' type, usually a 64-bit unsigned integer.
	operator ulonglong() const
			{ return conv(static_cast<ulonglong>(0)); }
#endif
	
	/// \brief Converts this object's string data to a float
	operator float() const
			{ return conv(static_cast<float>(0)); }
	
	/// \brief Converts this object's string data to a double
	operator double() const
			{ return conv(static_cast<double>(0)); }
	
	/// \brief Converts this object's string data to a bool
	operator bool() const { return conv(0); }

	template <class T, class B> operator Null<T, B>() const;

private:
	mysql_type_info type_;
	mutable std::string temp_buf_;	
	bool null_;
};

/// \typedef ColData_Tmpl<const_string> ColData
/// \brief The type that is returned by constant rows
typedef ColData_Tmpl<const_string> ColData;

/// \typedef ColData_Tmpl<std::string> MutableColData
/// \brief The type that is returned by mutable rows
typedef ColData_Tmpl<std::string> MutableColData;


#if !defined(NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
// Ignore this section is NO_BINARY_OPERS is defined, or if this section
// is being parsed by Doxygen.  In the latter case, it's ignored because
// Doxygen doesn't understand it correctly, and we can't be bothered to
// explain it to Doxygen.

#define oprsw(opr, other, conv) \
  template<class Str> \
  inline other operator opr (ColData_Tmpl<Str> x, other y) \
    {return static_cast<conv>(x) opr y;} \
  template<class Str> \
  inline other operator opr (other x, ColData_Tmpl<Str> y) \
    {return x opr static_cast<conv>(y);}

#define operator_binary(other, conv) \
  oprsw(+, other, conv) \
  oprsw(-, other, conv) \
  oprsw(*, other, conv) \
  oprsw(/, other, conv)

#define operator_binary_int(other, conv) \
  operator_binary(other, conv) \
  oprsw(%, other, conv) \
  oprsw(&, other, conv) \
  oprsw(^, other, conv) \
  oprsw(|, other, conv) \
  oprsw(<<, other, conv) \
  oprsw(>>, other, conv)

operator_binary(float, double)
operator_binary(double, double)

operator_binary_int(char, long int)
operator_binary_int(int, long int)
operator_binary_int(short int, long int)
operator_binary_int(long int, long int)

operator_binary_int(unsigned char, unsigned long int)
operator_binary_int(unsigned int, unsigned long int)
operator_binary_int(unsigned short int, unsigned long int)
operator_binary_int(unsigned long int, unsigned long int)

#if !defined(NO_LONG_LONGS)
operator_binary_int(longlong, longlong)
operator_binary_int(ulonglong, ulonglong)
#endif
#endif // NO_BINARY_OPERS

/// \brief Converts this object to a SQL null
///
/// Returns a copy of the global null object if the string data held by
/// the object is exactly equal to "NULL".  Else, it constructs an empty
/// object of type T and tries to convert it to Null<T, B>.
template <class Str> template<class T, class B>
ColData_Tmpl<Str>::operator Null<T, B>() const
{
	if ((Str::size() == 4) &&
			(*this)[0] == 'N' &&
			(*this)[1] == 'U' &&
			(*this)[2] == 'L' &&
			(*this)[3] == 'L') {
		return Null<T, B>(null);
	}
	else {
		return Null<T, B>(conv(T()));
	}
}

template <class Str> template <class Type>
Type ColData_Tmpl<Str>::conv(Type /* dummy */) const
{
	std::string strbuf(Str::data(), Str::length());
	strip_all_blanks(strbuf);
	std::string::size_type len = strbuf.size();
	const char* str = strbuf.c_str();
	const char* end = str;
	Type num = mysql_convert<Type>(str, end);

	if (*end == '.') {
		++end;
		for (; *end == '0'; ++end) ;
	}
	
	if (*end != '\0' && end != 0) {
		throw BadConversion(typeid(Type).name(), Str::c_str(),
				end - str, len);
	}

	return num;
}

} // end namespace mysqlpp

#endif
Deleted lib/common.h.
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

































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file common.h
/// \brief This file includes top-level definitions for use both
/// internal to the library, and outside it.  Contrast mysql++.h
///
/// This file mostly takes care of platform differences.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#if !defined(MYSQLPP_COMMON_H)
#define MYSQLPP_COMMON_H

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for the following stuff.

// Work out major platform-specific stuff here.
#if defined(__WIN32__) || defined(_WIN32)
#	define MYSQLPP_PLATFORM_WINDOWS

	// Windows compiler support.  Tested with Microsoft Visual C++,
	// Borland C++ Builder, and MinGW GCC.
#	include <winsock.h>

	// Stuff for Visual C++ only
#	if defined(_MSC_VER)
		// Disable whining about using 'this' as a member initializer on VC++.
#		pragma warning(disable: 4355)
		// Disable whining about implicit conversions to bool
#		pragma warning(disable: 4800)
		// Disable nagging about new "secure" functions like strncpy_s()
#		pragma warning(disable: 4996)
		// Disable complaints about STL data members: VC++ believes
		// these need to be __declspec(dllexport) for some reason.
#		pragma warning(disable: 4251)
		// Call _snprintf() for VC++ version of snprintf() function
#		define snprintf _snprintf
#	endif

	// Define DLL import/export tags for Windows compilers, where we build
	// the library into a DLL, for LGPL license compatibility reasons.
	// (This is based on a similar mechanism in wxWindows.)

	#ifdef MYSQLPP_MAKING_DLL
		// When making the DLL, export tagged symbols, so they appear
		// in the import library.
		#define MYSQLPP_EXPORT __declspec(dllexport)
	#elif !defined(MYSQLPP_NO_DLL)
		// We must be _using_ the DLL, so import symbols instead.
		#define MYSQLPP_EXPORT __declspec(dllimport)
	#else
		// Not making a DLL at all, so no-op these declspecs
		#define MYSQLPP_EXPORT
	#endif
#else
	// If not Windows, we assume some sort of Unixy build environment,
	// where autotools is used.  (This includes Cygwin!)  #include the
	// config.h file only if this file was included from a non-header
	// file, because headers must not be dependent on config.h.
#	if defined(MYSQLPP_NOT_HEADER)
#		include "config.h"
#	endif

	// Make DLL stuff a no-op on this platform.
	#define MYSQLPP_EXPORT
#endif

#if defined(MYSQLPP_MYSQL_HEADERS_BURIED)
#	include <mysql/mysql_version.h>
#else
#	include <mysql_version.h>
#endif

namespace mysqlpp {

/// \brief Alias for 'true', to make code requesting exceptions more
/// readable.
const bool use_exceptions = true;

/// \brief Used to disambiguate overloads of equal_list() in SSQLSes.
enum sql_cmp_type { sql_use_compare };

#if !defined(DOXYGEN_IGNORE)
// Figure out how to get large integer support on this system.  Suppress
// refman documentation for these typedefs, as they're system-dependent.
#if defined(NO_LONG_LONGS)
// Alias "longlong" and "ulonglong" to the regular "long" counterparts
typedef unsigned long ulonglong;
typedef long longlong;
#elif defined(_MSC_VER)
// It's VC++, so we'll use Microsoft's 64-bit integer types
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
#else
// No better idea, so assume the C99 convention.  If your compiler
// doesn't support this, please provide a patch to extend this ifdef, or
// define NO_LONG_LONGS.
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif
#endif // !defined(DOXYGEN_IGNORE)

/// \brief Contraction for 'const char*'
typedef const char cchar;

#if !defined(MYSQLPP_NO_UNSIGNED_INT_TYPES)
/// \brief Contraction for 'unsigned int'
typedef unsigned int uint;
/// \brief Contraction for 'unsigned long'
typedef unsigned long ulong;
#endif

} // end namespace mysqlpp

// The MySQL headers define these macros, which is completely wrong in a
// C++ project.  Undo the damage.
#undef min
#undef max

#endif // !defined(DOXYGEN_IGNORE)


// Now that we've defined all the stuff above, we can pull in the full
// MySQL header.  Basically, the above largely replaces MySQL's my_global.h
// while actually working with C++.  This is why we disobey the MySQL
// developer docs, which recommend including my_global.h before mysql.h.
#if defined(MYSQLPP_MYSQL_HEADERS_BURIED)
#	include <mysql/mysql.h>
#else
#	include <mysql.h>
#endif


namespace mysqlpp {

/// \brief Alias for MYSQL_FIELD
typedef MYSQL_FIELD Field;

} // end namespace mysqlpp

#endif // !defined(MYSQLPP_COMMON_H)
Deleted lib/connection.cpp.
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





















































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 connection.cpp - Implements the Connection class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "connection.h"

#include "query.h"
#include "result.h"

// An argument was added to mysql_shutdown() in MySQL 4.1.3 and 5.0.1.
#if ((MYSQL_VERSION_ID >= 40103) && (MYSQL_VERSION_ID <= 49999)) || (MYSQL_VERSION_ID >= 50001)
#	define SHUTDOWN_ARG ,SHUTDOWN_DEFAULT
#else
#	define SHUTDOWN_ARG
#endif

#define NELEMS(a) (sizeof(a) / sizeof(a[0]))

using namespace std;

namespace mysqlpp {

/// \brief Sets a variable to a given value temporarily.
///
/// Saves existing value, sets new value, and restores old value when
/// the object is destroyed.  Used to set a flag in an exception-safe
/// manner.
template <class T>
class scoped_var_set
{
public:
	/// \brief Create object, saving old value, setting new value
	scoped_var_set(T& var, T new_value) :
	var_(var)
	{
		old_value_ = var_;
		var_ = new_value;
	}

	/// \brief Destroy object, restoring old value
	~scoped_var_set()
	{
		var_ = old_value_;
	}

private:
	T& var_;
	T old_value_;
};


// Initialize table of legal option argument types.
Connection::OptionArgType
Connection::legal_opt_arg_types_[Connection::opt_COUNT] = {
	Connection::opt_type_integer,	// opt_connect_timeout
	Connection::opt_type_none,		// opt_compress
	Connection::opt_type_none,		// opt_named_pipe
	Connection::opt_type_string,	// opt_init_command
	Connection::opt_type_string,	// opt_read_default_file
	Connection::opt_type_string,	// opt_read_default_group
	Connection::opt_type_string,	// opt_set_charset_dir
	Connection::opt_type_string,	// opt_set_charset_name
	Connection::opt_type_integer,	// opt_local_infile
	Connection::opt_type_integer,	// opt_protocol
	Connection::opt_type_string,	// opt_shared_memory_base_name
	Connection::opt_type_integer,	// opt_read_timeout
	Connection::opt_type_integer,	// opt_write_timeout
	Connection::opt_type_none,		// opt_use_result
	Connection::opt_type_none,		// opt_use_remote_connection
	Connection::opt_type_none,		// opt_use_embedded_connection
	Connection::opt_type_none,		// opt_guess_connection
	Connection::opt_type_string,	// opt_set_client_ip
	Connection::opt_type_boolean,	// opt_secure_auth
	Connection::opt_type_boolean,	// opt_multi_statements
	Connection::opt_type_boolean,	// opt_report_data_truncation
	Connection::opt_type_boolean,   // opt_reconnect
};


Connection::Connection(bool te) :
OptionalExceptions(te),
Lockable(false),
is_connected_(false),
connecting_(false),
success_(false)
{
	mysql_init(&mysql_);
}


Connection::Connection(const char* db, const char* host,
		const char* user, const char* passwd, uint port,
		my_bool compress, unsigned int connect_timeout,
		cchar* socket_name, unsigned int client_flag) :
OptionalExceptions(),
Lockable(false),
connecting_(false)
{
	mysql_init(&mysql_);
	if (connect(db, host, user, passwd, port, compress,
			connect_timeout, socket_name, client_flag)) {
		unlock();
		success_ = is_connected_ = true;
	}
	else {
		unlock();
		success_ = is_connected_ = false;
		if (throw_exceptions()) {
			throw ConnectionFailed(error());
		}
	}
}


Connection::Connection(const Connection& other) :
OptionalExceptions(),
Lockable(false),
is_connected_(false)
{
	copy(other);
}


Connection::~Connection()
{
	disconnect();
}


Connection&
Connection::operator=(const Connection& rhs)
{
	copy(rhs);
	return *this;
}


bool
Connection::connect(cchar* db, cchar* host, cchar* user,
		cchar* passwd, uint port, my_bool compress,
		unsigned int connect_timeout, cchar* socket_name,
		unsigned int client_flag)
{
	lock();

	// Drop previous connection, if any
	if (connected()) {
		disconnect();
	}

	// Set defaults for certain connection options.  User can override
	// these by calling set_option() before connect().
	set_option_default(opt_read_default_file, "my");
	set_option_default(opt_connect_timeout, connect_timeout);
	if (compress) {
		set_option_default(opt_compress);
	}

#if MYSQL_VERSION_ID >= 40101
	// Check to see if user turned on multi-statements before
	// establishing the connection.  This one we handle specially, by
	// setting a flag during connection establishment.
	if (option_set(opt_multi_statements)) {
		client_flag |= CLIENT_MULTI_STATEMENTS;
	}
#endif

	// Establish connection
	scoped_var_set<bool> sb(connecting_, true);
	if (mysql_real_connect(&mysql_, host, user, passwd, db, port,
			socket_name, client_flag)) {
		unlock();
		success_ = is_connected_ = true;

		if (db && db[0]) {
			// Also attach to given database
			success_ = select_db(db);
		}
	}
	else {
		unlock();
		success_ = is_connected_ = false;
		if (throw_exceptions()) {
			throw ConnectionFailed(error());
		}
	}

	return success_;
}


bool
Connection::connect(const MYSQL& mysql)
{
	return connect(mysql.db, mysql.host, mysql.user, mysql.passwd,
			mysql.port, mysql.options.compress,
			mysql.options.connect_timeout, mysql.unix_socket,
			mysql.client_flag);
}


void
Connection::copy(const Connection& other)
{
	if (connected()) {
		disconnect();
	}

	mysql_init(&mysql_);
	set_exceptions(other.throw_exceptions());

	if (other.connected()) {
		// Try to reconnect to server using same parameters
		connect(other.mysql_);
	}
	else {
		is_connected_ = false;
		connecting_ = false;
		success_ = false;
	}
}


void
Connection::disconnect()
{
	mysql_close(&mysql_);
	is_connected_ = false;
}


bool
Connection::create_db(const std::string& db)
{
	Query q(this, throw_exceptions());
	return q.exec("CREATE DATABASE " + db);
}


bool
Connection::drop_db(const std::string& db)
{
	Query q(this, throw_exceptions());
	return q.exec("DROP DATABASE " + db);
}


bool
Connection::select_db(const char *db)
{
	if (connected()) {
		bool suc = !(mysql_select_db(&mysql_, db));
		if (throw_exceptions() && !suc) {
			throw DBSelectionFailed(error());
		}
		else {
			return suc;
		}
	}
	else {
		if (throw_exceptions()) {
			throw DBSelectionFailed("MySQL++ connection not established");
		}
		else {
			return false;
		}
	}
}


bool
Connection::reload()
{
	if (connected()) {
		bool suc = !mysql_reload(&mysql_);
		if (throw_exceptions() && !suc) {
			// Reloading grant tables through this API isn't precisely a
			// query, but it's acceptable to signal errors with BadQuery
			// because the new mechanism is the FLUSH PRIVILEGES query.
			// A program won't have to change when doing it the new way.
			throw BadQuery(error());
		}
		else {
			return suc;
		}
	}
	else {
		if (throw_exceptions()) {
			throw BadQuery("MySQL++ connection not established");
		}
		else {
			return false;
		}
	}
}


bool
Connection::shutdown()
{
	if (connected()) {
		bool suc = !(mysql_shutdown(&mysql_ SHUTDOWN_ARG));
		if (throw_exceptions() && !suc) {
			throw ConnectionFailed(error());
		}
		else {
			return suc;
		}
	}
	else {
		if (throw_exceptions()) {
			throw ConnectionFailed("MySQL++ connection not established");
		}
		else {
			return false;
		}
	}
}


string
Connection::info()
{
	const char* i = mysql_info(&mysql_);
	if (!i) {
		return string();
	}
	else {
		return string(i);
	}
}


Query
Connection::query()
{
	return Query(this, throw_exceptions());
}


bool
Connection::set_option(Option option)
{
	if (connected()) {
		// None of the argument-less options can be set once the
		// connection is up.
		return bad_option(option, opt_err_conn);
	}
	
	bool success = false;
	switch (option) {
		case opt_compress:
			success = set_option_impl(MYSQL_OPT_COMPRESS);
			break;

		case opt_named_pipe:
			success = set_option_impl(MYSQL_OPT_NAMED_PIPE);
			break;

#if MYSQL_VERSION_ID >= 40101
		case opt_use_result:
			success = set_option_impl(MYSQL_OPT_USE_RESULT);
			break;

		case opt_use_remote_connection:
			success = set_option_impl(MYSQL_OPT_USE_REMOTE_CONNECTION);
			break;

		case opt_use_embedded_connection:
			success = set_option_impl(MYSQL_OPT_USE_EMBEDDED_CONNECTION);
			break;

		case opt_guess_connection:
			success = set_option_impl(MYSQL_OPT_GUESS_CONNECTION);
			break;
#endif
		default:
			return bad_option(option, opt_err_type);
	}

	if (success) {
		applied_options_.push_back(OptionInfo(option));
		return true;
	}
	else {
		return bad_option(option, opt_err_value);
	}
}


bool
Connection::set_option(Option option, const char* arg)
{
	if (connected()) {
		// None of the options taking a char* argument can be set once
		// the connection is up.
		return bad_option(option, opt_err_conn);
	}

	bool success = false;
	switch (option) {
		case opt_init_command:
			success = set_option_impl(MYSQL_INIT_COMMAND, arg);
			break;

		case opt_read_default_file:
			success = set_option_impl(MYSQL_READ_DEFAULT_FILE, arg);
			break;

		case opt_read_default_group:
			success = set_option_impl(MYSQL_READ_DEFAULT_GROUP, arg);
			break;

		case opt_set_charset_dir:
			success = set_option_impl(MYSQL_SET_CHARSET_DIR, arg);
			break;

		case opt_set_charset_name:
			success = set_option_impl(MYSQL_SET_CHARSET_NAME, arg);
			break;

#if MYSQL_VERSION_ID >= 40100
		case opt_shared_memory_base_name:
			success = set_option_impl(MYSQL_SHARED_MEMORY_BASE_NAME, arg);
			break;
#endif
#if MYSQL_VERSION_ID >= 40101
		case opt_set_client_ip:
			success = set_option_impl(MYSQL_SET_CLIENT_IP, arg);
			break;
#endif
		default:
			return bad_option(option, opt_err_type);
	}

	if (success) {
		applied_options_.push_back(OptionInfo(option, arg));
		return true;
	}
	else {
		return bad_option(option, opt_err_value);
	}
}


bool
Connection::set_option(Option option, unsigned int arg)
{
	if (connected()) {
		// None of the options taking an int argument can be set once
		// the connection is up.
		return bad_option(option, opt_err_conn);
	}

	bool success = false;
	switch (option) {
		case opt_connect_timeout:
			success = set_option_impl(MYSQL_OPT_CONNECT_TIMEOUT, &arg);
			break;

		case opt_local_infile:
			success = set_option_impl(MYSQL_OPT_LOCAL_INFILE, &arg);
			break;

#if MYSQL_VERSION_ID >= 40100
		case opt_protocol:
			success = set_option_impl(MYSQL_OPT_PROTOCOL, &arg);
			break;
#endif
#if MYSQL_VERSION_ID >= 40101
		case opt_read_timeout:
			success = set_option_impl(MYSQL_OPT_READ_TIMEOUT, &arg);
			break;

		case opt_write_timeout:
			success = set_option_impl(MYSQL_OPT_WRITE_TIMEOUT, &arg);
			break;
#endif
		default:
			return bad_option(option, opt_err_type);
	}

	if (success) {
		applied_options_.push_back(OptionInfo(option, arg));
		return true;
	}
	else {
		return bad_option(option, opt_err_value);
	}
}


bool
Connection::set_option(Option option, bool arg)
{
	if (connected() && (option != opt_multi_statements)) {
		// We're connected and it isn't an option that can be set
		// after connection is up, so complain to user.
		return bad_option(option, opt_err_conn);
	}

	bool success = false;
	switch (option) {
#if MYSQL_VERSION_ID >= 40101
		case opt_secure_auth:
			success = set_option_impl(MYSQL_SECURE_AUTH, &arg);
			break;

		case opt_multi_statements:
			// If connection is up, set the flag immediately.  If not,
			// and caller wants this turned on, pretend success so that
			// we store the info we need to turn this flag on when
			// bringing the connection up.  (If the caller is turning it
			// off before conn comes up, we effectively ignore this, 
			// because that's the default.)
			if (connected()) {
				success = set_option_impl(arg ?
						MYSQL_OPTION_MULTI_STATEMENTS_ON :
						MYSQL_OPTION_MULTI_STATEMENTS_OFF);
			}
			else {
				success = arg;
			}
			break;
#endif
#if MYSQL_VERSION_ID >= 50003
		case opt_report_data_truncation:
			success = set_option_impl(MYSQL_REPORT_DATA_TRUNCATION, &arg);
			break;
#endif
#if MYSQL_VERSION_ID >= 50013
		case opt_reconnect:
			success = set_option_impl(MYSQL_OPT_RECONNECT, &arg);
			break;
#endif
		default:
			return bad_option(option, opt_err_type);
	}

	if (success) {
		applied_options_.push_back(OptionInfo(option, arg));
		return true;
	}
	else {
		return bad_option(option, opt_err_value);
	}
}


bool
Connection::set_option_default(Option option)
{
	if (option_set(option)) {
		return true;
	}
	else {
		return set_option(option);
	}
}


template <typename T>
bool
Connection::set_option_default(Option option, T arg)
{
	if (option_set(option)) {
		return true;
	}
	else {
		return set_option(option, arg);
	}
}


bool
Connection::set_option_impl(mysql_option moption, const void* arg)
{
	return !mysql_options(&mysql_, moption,
			static_cast<const char*>(arg));
}


#if MYSQL_VERSION_ID >= 40101
bool
Connection::set_option_impl(enum_mysql_set_option msoption)
{
	return !mysql_set_server_option(&mysql_, msoption);
}
#endif


bool
Connection::bad_option(Option option, OptionError error)
{
	if (throw_exceptions()) {
		ostringstream os;

		switch (error) {
			case opt_err_type: {
				// Option was set using wrong argument type
				OptionArgType type = option_arg_type(option);
				os << "option " << option;
				if (type == opt_type_none) {
					os << " does not take an argument";
				}
				else {
					os << " requires an argument of type " << type;
				}
				break;
			}

			case opt_err_value:
				// C API rejected option, which probably indicates that
				// you passed a option that it doesn't understand.
				os << "option " << option << " not supported in MySQL "
						"C API v";
				api_version(os);
				break;

			case opt_err_conn:
				os << "option " << option << " can only be set "
						"before connection is established";
				break;
		}

		throw BadOption(os.str(), option);
	}

	return false;
}


Connection::OptionArgType
Connection::option_arg_type(Option option)
{
	if ((option > opt_FIRST) && (option < opt_COUNT)) {
		return legal_opt_arg_types_[option];
	}
	else {
		// Non-optional exception.  Something is wrong with the library
		// internals if this one is thrown.
		throw BadOption("bad value given to option_arg_type()", option);
	}
}


bool
Connection::option_set(Option option)
{
	for (OptionListIt it = applied_options_.begin();
			it != applied_options_.end(); 
			++it) {
		if (it->option == option) {
			return true;
		}
	}

	return false;
}


void
Connection::enable_ssl(const char* key, const char* cert,
		const char* ca, const char* capath, const char* cipher)
{
#if defined(HAVE_MYSQL_SSL_SET)
	mysql_ssl_set(&mysql_, key, cert, ca, capath, cipher);
#endif
}


ostream&
Connection::api_version(ostream& os)
{
	const int major = MYSQL_VERSION_ID / 10000;
	const int minor = (MYSQL_VERSION_ID - (major * 10000)) / 100;
	const int bug = MYSQL_VERSION_ID - (major * 10000) - (minor * 100);

	os << major << '.' << minor << '.' << bug;

	return os;
}


int
Connection::ping()
{
	if (connected()) {
		return mysql_ping(&mysql_);
	}
	else {
		// Not connected, and we've forgotten everything we need in
		// order to re-connect, if we once were connected.
		return 1;
	}
}


} // end namespace mysqlpp

Deleted lib/connection.h.
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



































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file connection.h
/// \brief Declares the Connection class.
///
/// Every program using MySQL++ must create a Connection object, which
/// manages information about the connection to the MySQL database, and
/// performs connection-related operations once the connection is up.
/// Subordinate classes, such as Query and Row take their defaults as
/// to whether exceptions are thrown when errors are encountered from
/// the Connection object that created them, directly or indirectly.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_CONNECTION_H
#define MYSQLPP_CONNECTION_H

#include "common.h"

#include "lockable.h"
#include "noexceptions.h"

#include <deque>
#include <string>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT Query;
#endif

/// \brief Manages the connection to the MySQL database.

class MYSQLPP_EXPORT Connection : public OptionalExceptions, public Lockable
{
public:
	/// \brief Legal types of option arguments
	enum OptionArgType {
		opt_type_none,
		opt_type_string,
		opt_type_integer,
		opt_type_boolean
	};

	/// \brief Per-connection options you can set with set_option()
	///
	/// This is currently a combination of the MySQL C API
	/// \c mysql_option and \c enum_mysql_set_option enums.  It may
	/// be extended in the future.
	enum Option 
	{
		// Symbolic "first" option, before real options.  Never send
		// this to set_option()!
		opt_FIRST = -1,
		
		opt_connect_timeout = 0,
		opt_compress,
		opt_named_pipe,
		opt_init_command,
		opt_read_default_file,
		opt_read_default_group,
		opt_set_charset_dir,
		opt_set_charset_name,
		opt_local_infile,
		opt_protocol,
		opt_shared_memory_base_name,
		opt_read_timeout,
		opt_write_timeout,
		opt_use_result,
		opt_use_remote_connection,
		opt_use_embedded_connection,
		opt_guess_connection,
		opt_set_client_ip,
		opt_secure_auth,

		// Set multi-query statement support; no argument
		opt_multi_statements,

		// Set reporting of data truncation errors
		opt_report_data_truncation,

		// Enable or disable automatic reconnection to the server if
		// the connection is found to have been lost.
		opt_reconnect,

		// Number of options supported.  Never send this to
		// set_option()!
		opt_COUNT
	};

	/// \brief Create object without connecting it to the MySQL server.
	///
	/// \param te if true, exceptions are thrown on errors
	Connection(bool te = true);

	/// \brief Create object and connect to database server in one step.
	///
	/// This constructor allows you to most fully specify the options
	/// used when connecting to the MySQL database.  It is the thinnest
	/// layer in MySQL++ over the MySQL C API function
	/// \c mysql_real_connect().  The correspondence isn't exact as
	/// we have some additional parameters you'd have to set with
	/// \c mysql_option() when using the C API.
	///
	/// \param db name of database to use
	/// \param host host name or IP address of MySQL server, or 0
	/// 	if server is running on the same host as your program
	/// \param user user name to log in under, or 0 to use the user
	///		name this program is running under
	/// \param passwd password to use when logging in
	/// \param port TCP port number MySQL server is listening on, or 0
	///		to use default value
	/// \param compress if true, compress data passing through
	///		connection, to save bandwidth at the expense of CPU time
	/// \param connect_timeout max seconds to wait for server to
	///		respond to our connection attempt
	/// \param socket_name Unix domain socket server is using, if
	///		connecting to MySQL server on the same host as this program
	///		running on, or 0 to use default name
	///	\param client_flag special connection flags. See MySQL C API
	///		documentation for \c mysql_real_connect() for details.
	Connection(const char* db, const char* host = "",
			const char* user = "", const char* passwd = "",
			uint port = 0, my_bool compress = 0,
			unsigned int connect_timeout = 60, cchar* socket_name = 0,
			unsigned int client_flag = 0);

	/// \brief Establish a new connection using the same parameters as
	/// an existing C API connection.
	///
	/// \param other existing Connection object
	Connection(const Connection& other);

	/// \brief Establish a new connection using the same parameters as
	/// an existing C API connection.
	///
	/// \param mysql existing MySQL C API connection object
	bool connect(const MYSQL& mysql);

	/// \brief Destroy connection object
	~Connection();

	/// \brief Connect to database after object is created.
	///
	/// It's better to use the connect-on-create constructor if you can.
	/// See its documentation for the meaning of these parameters.
	///
	/// If you call this method on an object that is already connected
	/// to a database server, the previous connection is dropped and a
	/// new connection is established.
	bool connect(cchar* db = "", cchar* host = "",
			cchar* user = "", cchar* passwd = "", uint port = 0,
			my_bool compress = 0, unsigned int connect_timeout = 60,
			cchar* socket_name = 0, unsigned int client_flag = 0);

	/// \brief Close connection to MySQL server.
	///
	/// Closes the connection to the MySQL server.
	void close()
	{
		mysql_close(&mysql_);
		is_connected_ = false;
	}
	
	/// \brief Calls MySQL C API function \c mysql_info() and returns
	/// result as a C++ string.
	std::string info();

	/// \brief return true if connection was established successfully
	///
	/// \return true if connection was established successfully
	bool connected() const
	{
		return is_connected_;
	}

	/// \brief Return true if the last query was successful
	bool success() const
	{
		return success_;
	}

	/// \brief Alias for close()
	void purge() { close(); }

	/// \brief Return a new query object.
	///
	/// The returned query object is tied to this MySQL connection,
	/// so when you call a method like
	/// \link mysqlpp::Query::execute() execute() \endlink
	/// on that object, the query is sent to the server this object
	/// is connected to.
	Query query();

	/// \brief Alias for success()
	///
	/// Alias for success() member function. Allows you to have code
	/// constructs like this:
	///
	/// \code
	///	    Connection conn;
	///	    .... use conn
	///	    if (conn) {
	///	        ... last SQL query was successful
	///	    }
	///	    else {
	///	        ... error occurred in SQL query
	///	    }
	/// \endcode
	operator bool() { return success(); }

	/// \brief Copy an existing Connection object's state into this
	/// object.
	Connection& operator=(const Connection& rhs);

	/// \brief Return error message for last MySQL error associated with
	/// this connection.
	///
	/// Simply wraps \c mysql_error() in the C API.
	const char* error()
	{
		return mysql_error(&mysql_);
	}

	/// \brief Return last MySQL error number associated with this
	/// connection
	///
	/// Simply wraps \c mysql_errno() in the C API.
	int errnum() { return mysql_errno(&mysql_); }

	/// \brief Wraps MySQL C API function \c mysql_refresh()
	///
	/// The corresponding C API function is undocumented.  All I know
	/// is that it's used by \c mysqldump and \c mysqladmin, according
	/// to MySQL bug database entry http://bugs.mysql.com/bug.php?id=9816
	/// If that entry changes to say that the function is now documented,
	/// reevaluate whether we need to wrap it.  It may be that it's not
	/// supposed to be used by regular end-user programs.
	int refresh(unsigned int refresh_options)
	{
		return mysql_refresh(&mysql_, refresh_options);
	}

	/// \brief "Pings" the MySQL database
	///
	/// Wraps \c mysql_ping() in the C API.  As a result, this function
	/// will try to reconnect to the server if the connection has been
	/// dropped.
	/// 
	/// \retval 0 if server is responding, regardless of whether we had
	/// to reconnect or not
	/// \retval nonzero if either we already know the connection is down
	/// and cannot re-establish it, or if the server did not respond to
	/// the ping and we could not re-establish the connection.
	int ping();

	/// \brief Kill a MySQL server thread
	///
	/// \param pid ID of thread to kill
	///
	/// Simply wraps \c mysql_kill() in the C API.
	int kill(unsigned long pid)
	{
		return mysql_kill(&mysql_, pid);
	}

	/// \brief Get MySQL client library version
	///
	/// Simply wraps \c mysql_get_client_info() in the C API.
	std::string client_info()
	{
		return std::string(mysql_get_client_info());
	}

	/// \brief Get information about the network connection
	///
	/// String contains info about type of connection and the server
	/// hostname.
	///
	/// Simply wraps \c mysql_get_host_info() in the C API.
	std::string host_info()
	{
		return std::string(mysql_get_host_info(&mysql_));
	}

	/// \brief Returns version number of MySQL protocol this connection
	/// is using
	///
	/// Simply wraps \c mysql_get_proto_info() in the C API.
	int proto_info() 
	{
		return mysql_get_proto_info(&mysql_);
	}

	/// \brief Get the MySQL server's version number
	///
	/// Simply wraps \c mysql_get_server_info() in the C API.
	std::string server_info()
	{
		return std::string(mysql_get_server_info(&mysql_));
	}

	/// \brief Returns information about MySQL server status
	///
	/// String is similar to that returned by the \c mysqladmin
	/// \c status command.  Among other things, it contains uptime 
	/// in seconds, and the number of running threads, questions
	/// and open tables.
	std::string stat()
	{
		return std::string(mysql_stat(&mysql_));
	}

	/// \brief Create a database
	///
	/// \param db name of database to create
	///
	/// \return true if database was created successfully
	bool create_db(const std::string& db);

	/// \brief Drop a database
	///
	/// \param db name of database to destroy
	///
	/// \return true if database was created successfully
	bool drop_db(const std::string& db);

	/// \brief Change to a different database
	bool select_db(const std::string& db)
	{
		return select_db(db.c_str());
	}

	/// \brief Change to a different database
	bool select_db(const char* db);

	/// \brief Ask MySQL server to reload the grant tables
	/// 
	/// User must have the "reload" privilege.
	///
	/// Simply wraps \c mysql_reload() in the C API.  Since that
	/// function is deprecated, this one is, too.  The MySQL++
	/// replacement is execute("FLUSH PRIVILEGES").
	bool reload();
	
	/// \brief Ask MySQL server to shut down.
	///
	/// User must have the "shutdown" privilege.
	///
	/// Simply wraps \c mysql_shutdown() in the C API.
	bool shutdown();

	/// \brief Return the connection options object
	st_mysql_options get_options() const
	{
		return mysql_.options;
	}

	/// \brief Sets a connection option, with no argument
	///
	/// \param option any of the Option enum constants
	///
	/// Based on the option you give, this function calls either
	/// \c mysql_options() or \c mysql_set_server_option() in the C API.
	///
	/// There are several overloaded versions of this function.  The
	/// others take an additional argument for the option and differ
	/// only by the type of the option.  Unlike with the underlying C
	/// API, it does matter which of these overloads you call: if you
	/// use the wrong argument type or pass an argument where one is
	/// not expected (or vice versa), the call will either throw an
	/// exception or return false, depending on the object's "throw
	/// exceptions" flag.
	///
	/// This mechanism parallels the underlying C API structure fairly
	/// closely, but do not expect this to continue in the future.
	/// Its very purpose is to 'paper over' the differences among the
	/// C API's option setting mechanisms, so it may become further
	/// abstracted from these mechanisms.
	///
	/// \retval true if option was successfully set, or at least queued
	/// for setting during connection establishment sequence
	///
	/// If exceptions are enabled, a false return means the C API
	/// rejected the option, or the connection is not established and
	/// so the option was queued for later processing.  If exceptions
	/// are disabled, false can also mean that the argument was of the
	/// wrong type (wrong overload was called), the option value was out
	/// of range, or the option is not supported by the C API, most
	/// because it isn't a high enough version. These latter cases will
	/// cause BadOption exceptions otherwise.
	bool set_option(Option option);

	/// \brief Sets a connection option, with string argument
	bool set_option(Option option, const char* arg);

	/// \brief Sets a connection option, with integer argument
	bool set_option(Option option, unsigned int arg);

	/// \brief Sets a connection option, with Boolean argument
	bool set_option(Option option, bool arg);

	/// \brief Same as set_option(), except that it won't override
	/// a previously-set option.
	bool set_option_default(Option option);

	/// \brief Same as set_option(), except that it won't override
	/// a previously-set option.
	template <typename T>
	bool set_option_default(Option option, T arg);

	/// \brief Returns true if the given option has been set already
	bool option_set(Option option);

	/// \brief Enable SSL-encrypted connection.
	///
	/// \param key the pathname to the key file
	/// \param cert the pathname to the certificate file
	/// \param ca the pathname to the certificate authority file
	/// \param capath directory that contains trusted SSL CA
	///        certificates in pem format.
    /// \param cipher list of allowable ciphers to use
	///
	/// Must be called before connection is established.
	///
	/// Wraps \c mysql_ssl_set() in MySQL C API.
	void enable_ssl(const char* key = 0,
			const char* cert = 0, const char* ca = 0,
			const char* capath = 0, const char* cipher = 0);

	/// \brief Return the number of rows affected by the last query
	///
	/// Simply wraps \c mysql_affected_rows() in the C API.
	my_ulonglong affected_rows()
	{
		return mysql_affected_rows(&mysql_);
	}

	/// \brief Get ID generated for an AUTO_INCREMENT column in the
	/// previous INSERT query.
	///
	/// \retval 0 if the previous query did not generate an ID.  Use
	/// the SQL function LAST_INSERT_ID() if you need the last ID
	/// generated by any query, not just the previous one.
	my_ulonglong insert_id()
	{
		return mysql_insert_id(&mysql_);
	}

	/// \brief Insert C API version we're linked against into C++ stream
	///
	/// Version will be of the form X.Y.Z, where X is the major version
	/// number, Y the minor version, and Z the bug fix number.
	std::ostream& api_version(std::ostream& os);

protected:
	/// \brief Types of option setting errors we can diagnose
	enum OptionError {
		opt_err_type,
		opt_err_value,
		opt_err_conn
	};
	
	/// \brief Drop the connection to the database server
	///
	/// This method is protected because it should only be used within
	/// the library.  Unless you use the default constructor, this
	/// object should always be connected.
	void disconnect();

	/// \brief Error handling routine for set_option()
	bool bad_option(Option option, OptionError error);

	/// \brief Given option value, return its proper argument type
	OptionArgType option_arg_type(Option option);

	/// \brief Set MySQL C API connection option
	///
	/// Wraps \c mysql_options() in C API.  This is an internal
	/// implementation detail, to be used only by the public overloads
	/// above.
	bool set_option_impl(mysql_option moption, const void* arg = 0);

#if MYSQL_VERSION_ID >= 40101
	/// \brief Set MySQL C API connection option
	///
	/// Wraps \c mysql_set_server_option() in C API.  This is an
	/// internal implementation detail, to be used only by the public
	/// overloads above.
	bool set_option_impl(enum_mysql_set_option msoption);
#endif

	/// \brief Establish a new connection as a copy of an existing one
	///
	/// \param other the connection to copy
	void copy(const Connection& other);

private:
	friend class ResNSel;
	friend class ResUse;
	friend class Query;

	struct OptionInfo {
		Option option;
		OptionArgType arg_type;
		std::string str_arg;
		unsigned int int_arg;
		bool bool_arg;

		OptionInfo(Option o) :
		option(o),
		arg_type(opt_type_none),
		int_arg(0),
		bool_arg(false)
		{
		}

		OptionInfo(Option o, const char* a) :
		option(o),
		arg_type(opt_type_string),
		str_arg(a),
		int_arg(0),
		bool_arg(false)
		{
		}

		OptionInfo(Option o, unsigned int a) :
		option(o),
		arg_type(opt_type_integer),
		int_arg(a),
		bool_arg(false)
		{
		}

		OptionInfo(Option o, bool a) :
		option(o),
		arg_type(opt_type_boolean),
		int_arg(0),
		bool_arg(a)
		{
		}
	};
	typedef std::deque<OptionInfo> OptionList;
	typedef OptionList::const_iterator OptionListIt;

	MYSQL mysql_;
	bool is_connected_;
	bool connecting_;
	bool success_;
	OptionList applied_options_;
	static OptionArgType legal_opt_arg_types_[];
};


} // end namespace mysqlpp

#endif

Deleted lib/const_string.h.
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



































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file const_string.h
/// \brief Declares a wrapper for <tt>const char*</tt> which behaves
/// in a way more useful to MySQL++.

/***********************************************************************
 Copyright © 1998 by Kevin Atkinson, © 1999, 2000 and 2001 by MySQL AB,
 and © 2004-2005, 2007, 2017 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_CONST_STRING_H
#define MYSQLPP_CONST_STRING_H

#include "common.h"

#include <algorithm>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>

namespace mysqlpp {

/// \brief Wrapper for <tt>const char*</tt> to make it behave in a
/// way more useful to MySQL++.
///
/// This class implements a small subset of the standard string class.
///
/// As of MySQL++ 2.3, it makes a copy of the string we are initialized
/// with, instead of just copying the pointer.  This is required to
/// avoid problems with the new SSQLS + BLOB support.
class MYSQLPP_EXPORT const_string
{
public:
	/// \brief Type of the data stored in this object, when it is not
	/// equal to SQL null.
	typedef const char value_type;

	/// \brief Type of "size" integers
	typedef unsigned int size_type;

	/// \brief Type used when returning a reference to a character in
	/// the string.
	typedef const char& const_reference;

	/// \brief Type of iterators
	typedef const char* const_iterator;

	/// \brief Same as const_iterator because the data cannot be
	/// changed.
	typedef const_iterator iterator;

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.
	typedef int difference_type;
	typedef const_reference reference;
	typedef const char* const_pointer;
	typedef const_pointer pointer;
#endif // !defined(DOXYGEN_IGNORE)

	/// \brief Create empty string
	const_string() :
	str_data_(0),
	length_(0)
	{
	}
	
	/// \brief Initialize string from existing C++ string
	const_string(const std::string& str) :
	str_data_(0),
	length_(str.length())
	{
		str_data_ = new char[length_ + 1];
		memcpy(str_data_, str.data(), length_);
		str_data_[length_] = '\0';
	}
	
	/// \brief Initialize string from existing C string
	const_string(const char* str) :
	str_data_(0),
	length_(size_type(strlen(str)))
	{
		str_data_ = new char[length_ + 1];
		memcpy(str_data_, str, length_);
		str_data_[length_] = '\0';
	}
	
	/// \brief Initialize string from existing C string of known length
	const_string(const char* str, size_type len) :
	str_data_(0),
	length_(size_type(len))
	{
		str_data_ = new char[length_ + 1];
		memcpy(str_data_, str, length_);
		str_data_[length_] = '\0';
	}

	/// \brief Destroy string
	~const_string()
	{
		delete[] str_data_;
	}
	
	/// \brief Assignment operator, from C string
	const_string& operator=(const char* str)
	{
		delete[] str_data_;
		length_ = size_type(strlen(str));
		str_data_ = new char[length_];
		memcpy(str_data_, str, length_);
		return *this;
	}

	/// \brief Assignment operator, from other const_string
	const_string& operator=(const const_string& cs)
	{
		delete[] str_data_;
		length_ = cs.length_;
		str_data_ = new char[length_];
		memcpy(str_data_, cs.str_data_, length_);
		return *this;
	}

	/// \brief Return number of characters in the string
	size_type length() const { return length_; }

	/// \brief Return number of characters in string
	size_type size() const { return length_; }

	/// \brief Return iterator pointing to the first character of
	/// the string
	const_iterator begin() const { return str_data_; }
	
	/// \brief Return iterator pointing to one past the last character
	/// of the string.
	const_iterator end() const { return str_data_ + size(); }
	
	/// \brief Return the maximum number of characters in the string.
	///
	/// Because this is a \c const string, this is just an alias for
	/// size(); its size is always equal to the amount of data currently
	/// stored.
	size_type max_size() const { return size(); }
	
	/// \brief Return a reference to a character within the string.
	const_reference operator [](size_type pos) const
			{ return str_data_[pos]; }
	
	/// \brief Return a reference to a character within the string.
	///
	/// Unlike \c operator[](), this function throws an 
	/// \c std::out_of_range exception if the index isn't within range.
	const_reference at(size_type pos) const
	{
		if (pos >= size())
			throw std::out_of_range("");
		else
			return str_data_[pos];
	}
	
	/// \brief Return a const pointer to the string data.  Not
	/// necessarily null-terminated!
	const char* c_str() const { return str_data_; }
	
	/// \brief Alias for \c c_str()
	const char* data() const { return str_data_; }
	
	/// \brief Lexically compare this string to another.
	///
	/// \param str string to compare against this one
	///
	/// \retval <0 if str1 is lexically "less than" str2
	/// \retval 0 if str1 is equal to str2
	/// \retval >0 if str1 is lexically "greater than" str2
	int compare(const const_string& str) const
	{
		size_type i = 0, short_len = std::min(length(), str.length());
		while ((i < short_len) && (str_data_[i] != str.str_data_[i])) {
			++i;
		}
		return str_data_[i] - str.str_data_[i];
	}

private:
	char* str_data_;
	size_type length_;
};


/// \brief Inserts a const_string into a C++ stream
inline std::ostream& operator <<(std::ostream& o,
		const const_string& str)
{
	return o << str.c_str();
}

/// \brief Calls lhs.compare(), passing rhs
inline int compare(const const_string& lhs, const const_string& rhs)
{
	return lhs.compare(rhs);
}

/// \brief Returns true if lhs is the same as rhs
inline bool operator ==(const_string& lhs, const_string& rhs)
{
	return compare(lhs, rhs) == 0;
}

/// \brief Returns true if lhs is not the same as rhs
inline bool operator !=(const_string& lhs, const_string& rhs)
{
	return compare(lhs, rhs) != 0;
}

/// \brief Returns true if lhs is lexically less than rhs
inline bool operator <(const_string& lhs, const_string& rhs)
{
	return compare(lhs, rhs) < 0;
}

/// \brief Returns true if lhs is lexically less or equal to rhs
inline bool operator <=(const_string& lhs, const_string& rhs)
{
	return compare(lhs, rhs) <= 0;
}

/// \brief Returns true if lhs is lexically greater than rhs
inline bool operator >(const_string& lhs, const_string& rhs)
{
	return compare(lhs, rhs) > 0;
}

/// \brief Returns true if lhs is lexically greater than or equal to rhs
inline bool operator >=(const_string& lhs, const_string& rhs)
{
	return compare(lhs, rhs) >= 0;
}

} // end namespace mysqlpp

#endif
Deleted lib/convert.h.
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





















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file convert.h
/// \brief Declares various string-to-integer type conversion templates.
///
/// These templates are the mechanism used within mysqlpp::ColData_Tmpl
/// for its string-to-\e something conversions.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_CONVERT_H
#define MYSQLPP_CONVERT_H

#include "common.h"

#include <stdlib.h>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

template <class Type> class mysql_convert;

#define mysql__convert(TYPE, FUNC) \
  template <> \
  class mysql_convert<TYPE> {\
  public:\
    mysql_convert(const char* str, const char *& end) { \
      num_ = FUNC(str, const_cast<char **>(&end));}\
    operator TYPE () {return num_;}\
  private:\
    TYPE num_;\
  };\

#if defined(_MSC_VER)
#	pragma warning(disable: 4244)
#endif

	mysql__convert(float, strtod)
	mysql__convert(double, strtod)

#if defined(_MSC_VER)
#	pragma warning(default: 4244)
#endif

#undef mysql__convert
#define mysql__convert(TYPE, FUNC) \
  template <> \
  class mysql_convert<TYPE> {\
  public:\
    mysql_convert(const char* str, const char *& end) { \
      num_ = FUNC(str, const_cast<char **>(&end),10);}\
    operator TYPE () {return num_;}\
  private:\
    TYPE num_;\
  };\

#if defined(_MSC_VER)
#	pragma warning(disable: 4244)
#endif

	mysql__convert(char, strtol)
	mysql__convert(signed char, strtol)
	mysql__convert(int, strtol)
	mysql__convert(short int, strtol)
	mysql__convert(long int, strtol)

	mysql__convert(unsigned char, strtoul)
	mysql__convert(unsigned int, strtoul)
	mysql__convert(unsigned short int, strtoul)
	mysql__convert(unsigned long int, strtoul)

#if defined(_MSC_VER)
#	pragma warning(default: 4244)
#endif

#if !defined(NO_LONG_LONGS)
#if defined(_MSC_VER)
// Handle 64-bit ints the VC++ way
mysql__convert(longlong, _strtoi64)
mysql__convert(ulonglong, _strtoui64)
#else
// No better idea, so assume the C99 way.  If your compiler doesn't
// support this, please provide a patch to extend this ifdef, or define
// NO_LONG_LONGS.
mysql__convert(longlong, strtoll)
mysql__convert(ulonglong, strtoull)
#endif
#endif // !defined(NO_LONG_LONGS)

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace mysqlpp

#endif

Deleted lib/custom-macros.h.

more than 10,000 changes

Deleted lib/custom.h.
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


































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This file is generated by the Perl script custom.pl. Please do 
// not modify this file directly. Change the script instead.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#ifndef MYSQLPP_CUSTOM_H
#define MYSQLPP_CUSTOM_H

#include "common.h"
#include "tiny_int.h"

#include <string>

#if defined(_MSC_VER) && (_MSC_VER < 1400)
#	error Please run the MySQL++ script lib/custom.pl with the -v compatibility flag.
#endif

#ifdef MYSQLPP_SSQLS_NO_STATICS
#	define MYSQLPP_SSQLS_EXPAND(...)
#else
#	define MYSQLPP_SSQLS_EXPAND(...) __VA_ARGS__
#endif

namespace mysqlpp {

enum sql_dummy_type {sql_dummy};

inline int sql_cmp(const std::string &a, const std::string &b) {
  return a.compare(b);
}

inline int sql_cmp(char a,char b) {
  return a-b;
}

inline int sql_cmp(unsigned char a,unsigned char b) {
  return a-b;
}

inline int sql_cmp(tiny_int a,tiny_int b) {
  return a-b;
}

inline int sql_cmp(int a,int b) {
  return a-b;
}

inline int sql_cmp(unsigned int a,unsigned int b) {
  return a-b;
}

inline int sql_cmp(short int a,short int b) {
  return a-b;
}

inline int sql_cmp(unsigned short int a,unsigned short int b) {
  return a-b;
}

inline int sql_cmp(unsigned long a,unsigned long b) {
  return a-b;
}

inline int sql_cmp(long a,long b) {
  return a-b;
}

inline int sql_cmp(double a,double b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}

inline int sql_cmp(float a,float b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}

inline int sql_cmp(longlong a,longlong b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}

inline int sql_cmp(ulonglong a,ulonglong b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}

#include "custom-macros.h"

} // end namespace mysqlpp

#endif

Deleted lib/custom.pl.
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




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/usr/bin/perl -w

########################################################################
# custom.pl - Generates custom.h and custom-macros.h, as these files
#	contain many near-duplicate classes, varying only in the number of
#	SQL table columns they support.
#
# Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
# MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
# Others may also hold copyrights on code in this file.  See the CREDITS
# file in the top directory of the distribution for details.
#
# This file is part of MySQL++.
#
# MySQL++ is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# MySQL++ is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with MySQL++; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
########################################################################


# This is the limit on the number of SSQLS data members.  Higher values
# will make custom-macros.h exponentially larger, increase compile
# times, and possibly even expose limits in your compiler.  Increase it
# only if you must.
my $max_data_members = 25;


# No user-serviceable parts below.

use strict;
use Getopt::Std;

our ($opt_v);
getopts('v') or die "usage: custom.pl [-v]\n";

open (OUT0, ">custom.h");
open (OUT, ">custom-macros.h");

print OUT0 << "---";

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This file is generated by the Perl script custom.pl. Please do 
// not modify this file directly. Change the script instead.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#ifndef MYSQLPP_CUSTOM_H
#define MYSQLPP_CUSTOM_H

#include "common.h"
#include "tiny_int.h"

#include <string>
---

my ($suppress_statics_start, $suppress_statics_end) = ('', '');
unless ($opt_v) {
	print OUT0 << "---";

#if defined(_MSC_VER) && (_MSC_VER < 1400)
#	error Please run the MySQL++ script lib/custom.pl with the -v compatibility flag.
#endif

#ifdef MYSQLPP_SSQLS_NO_STATICS
#	define MYSQLPP_SSQLS_EXPAND(...)
#else
#	define MYSQLPP_SSQLS_EXPAND(...) __VA_ARGS__
#endif

---
	$suppress_statics_start = 'MYSQLPP_SSQLS_EXPAND(';
	$suppress_statics_end = ')';
}

print OUT0 << "---";
namespace mysqlpp {

enum sql_dummy_type {sql_dummy};

inline int sql_cmp(const std::string &a, const std::string &b) {
  return a.compare(b);
}
---

my @types = ("char", "unsigned char", "tiny_int", "int", "unsigned int",
	  "short int", "unsigned short int", "unsigned long", "long");
foreach my $type (@types) {
    print OUT0 << "---";

inline int sql_cmp($type a,$type b) {
  return a-b;
}
---
}

@types = ("double", "float");
foreach my $type (@types) {
    print OUT0 << "---";

inline int sql_cmp($type a,$type b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}
---
}	

@types = ("longlong", "ulonglong");
foreach my $type (@types) {
    print OUT0 << "---";

inline int sql_cmp($type a,$type b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}
---
}	

print OUT0 << "---";

#include "custom-macros.h"

} // end namespace mysqlpp

#endif

---

print OUT << "---";

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This file is generated by the Perl script custom.pl. Please do 
// not modify this file directly. Change the script instead.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// ---------------------------------------------------
//                Begin Mandatory Compare 
// ---------------------------------------------------

#define sql_compare_define(NAME) \\
    bool operator == (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) == 0;} \\
    bool operator != (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) != 0;} \\
    bool operator > (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) >  0;} \\
    bool operator < (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) <  0;} \\
    bool operator >= (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) >= 0;} \\
    bool operator <= (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) <= 0;} \\
    int cmp (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other);} \\
    int compare (const NAME &other) const \\
      {return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other);}
---

my ($parm0, $parm1);

foreach my $j (1..$max_data_members) {
    $parm0 .= "T$j, C$j";
    $parm0 .= ", " unless $j == $max_data_members;
    $parm1 .= "C$j";
    $parm1 .= ", " unless $j == $max_data_members;
}

print OUT << "---";

#define sql_compare_define_0(NAME, $parm0)

#define sql_construct_define_0(NAME, $parm0)

#define sql_COMPARE__0(NAME, $parm1)

#define sql_compare_type_def_0(NAME, WHAT, NUM) \\
  sql_compare_type_def_##NUM (NAME, WHAT, NUM)

#define sql_compare_type_defe_0(NAME, WHAT, NUM) \\
  sql_compare_type_defe_##NUM (NAME, WHAT, NUM)

// ---------------------------------------------------
//                 End Mandatory Compare 
// ---------------------------------------------------
---


foreach my $i (1..$max_data_members) {
  my ($compr, $define, $compp, $set, $parm2);
  $compr = ""; $parm2 = ""; $define = "";
  $compr = "    int cmp; \\\n" unless $i == 1;
  $compp = "";
  $set = "";
  foreach my $j (1..$i) {
	  if ($j != $i) {
		  $compr .= "    cmp = mysqlpp::sql_cmp(x.C$j , y.C$j ); \\\n";
		  $compr .= "    if (cmp) return cmp; \\\n";
      }

      $compr .= "    return mysqlpp::sql_cmp(x.C$j , y.C$j );"   if $j == $i;
      $parm2 .= "const T$j &p$j";
      $parm2 .= ", "  unless $j == $i;
      $define.= "C$j (p$j)";
      $define.= ", "  unless $j == $i;
      $set   .= "    C$j = p$j;\\\n";
      $compp .= "true";
      $compp .= ", " unless $j == $i;
  }
  print OUT << "---";

// ---------------------------------------------------
//                   Begin Compare $i
// ---------------------------------------------------

#define sql_compare_define_$i(NAME, $parm0) \\
  NAME ($parm2) : $define {} \\
  void set  ($parm2) { \\
$set \\
  } \\
  sql_compare_define(NAME)

#define sql_construct_define_$i(NAME, $parm0) \\
  void set  ($parm2) { \\
$set \\
  } \\
  NAME ($parm2) : $define {}

#define sql_compare_type_def_$i(NAME, WHAT, NUM) \\
  return WHAT##_list(d, m, $compp)

#define sql_compare_type_defe_$i(NAME, WHAT, NUM) \\
  return WHAT##_list(d, c, m, $compp)

#define sql_COMPARE__$i(NAME, $parm1) \\
  template <mysqlpp::sql_dummy_type dummy> \\
  int sql_compare_##NAME (const NAME &x, const NAME &y) { \\
$compr \\
  } \\
  template <mysqlpp::sql_dummy_type dummy> \\
  int compare (const NAME &x, const NAME &y) { \\
$compr \\
  }

// ---------------------------------------------------
//                   End Compare $i
// ---------------------------------------------------

---
}

print OUT << "---";
---


foreach my $i (1..$max_data_members) {
    my $parm_complete = ""; 
    my $parm_order = ""; my $parm_order2c = "";
    my $parm_simple = ""; my $parm_simple2c = "";
    my $parm_simple_b = ""; my $parm_simple2c_b = "";
    my $parm_names = ""; my $parm_names2c = "";
    my $defs = ""; my $popul = ""; my $parmc = ""; my $parmC = "";
    my $value_list = ""; my $field_list = ""; my $equal_list = "";
    my $value_list_cus = ""; my $cus_field_list = ""; my $cus_equal_list = "";
    my $create_bool = ""; my $create_list = "";
    my $cusparms1 = ""; my $cusparms2 = ""; my $cusparmsv = "";    
    my $cusparms11 = ""; my $cusparms22 = "";
    my $names = "";my $enums = "";
    foreach my $j (1 .. $i) {
        $parm_complete .= "T$j, I$j, N$j, O$j";
	$parm_complete .= ", " unless $j == $i;
	$parm_order    .= "T$j, I$j, O$j";
	$parm_order    .= ", " unless $j == $i;
        $parm_order2c  .= "T$j, I$j, #I$j, O$j";
	$parm_order2c  .= ", " unless $j == $i;
        $parm_names    .= "T$j, I$j, N$j";
	$parm_names    .= ", " unless $j == $i;
	$parm_names2c  .= "T$j, I$j, N$j, ". ($j-1);
	$parm_names2c  .= ", " unless $j == $i;
	$parm_simple   .= "T$j, I$j";
	$parm_simple   .= ", " unless $j == $i;
	$parm_simple2c .= "T$j, I$j, #I$j, ". ($j-1);
	$parm_simple2c .= ", " unless $j == $i;
	$parm_simple_b   .= "T$j, I$j";
	$parm_simple_b   .= ", " unless $j == $i;
	$parm_simple2c_b .= "T$j, I$j, ". ($j-1);
	$parm_simple2c_b .= ", " unless $j == $i;
	$defs  .= "    T$j I$j;";
	$defs  .= "\n" unless $j == $i;
	$popul .= "    s->I$j = static_cast<T$j>(row.at(O$j));";
	$popul .= "\n" unless $j == $i;
        $names .= "    N$j ";
	$names .= ",\n" unless $j == $i;
        $enums .= "    NAME##_##I$j";
	$enums .= ",\n" unless $j == $i;
        $field_list .= "    s << obj.manip << obj.obj->names[".($j-1)."]";
	$field_list .= " << obj.delem;\n" unless $j == $i;
	$value_list .= "    s << obj.manip << obj.obj->I$j";
	$value_list .= " << obj.delem;\n" unless $j == $i;
        $create_bool .= "    if (i$j) (*include)[".($j-1)."]=true;\n";
        $create_list .= "    if (i$j == NAME##_NULL) return;\n" unless $i == 1;
        $create_list .= "    (*include)[i$j]=true;\n";

        $value_list_cus .= "    if ((*obj.include)[".($j-1)."]) { \n";
	$value_list_cus .= "      if (before) s << obj.delem;\n" unless $j == 1;
        $value_list_cus .= "      s << obj.manip << obj.obj->I$j;\n";
	$value_list_cus .= "      before = true; \n" unless $j == $i;
	$value_list_cus .= "     } \n";

        $cus_field_list .= "    if ((*obj.include)[".($j-1)."]) { \n";
	$cus_field_list .= "      if (before) s << obj.delem;\n" unless $j == 1;
        $cus_field_list .= "      s << obj.manip << obj.obj->names[".($j-1)."];\n";
	$cus_field_list .= "      before = true; \n" unless $j == $i;
	$cus_field_list .= "     } \n";

        $cus_equal_list .= "    if ((*obj.include)[".($j-1)."]) { \n";
	$cus_equal_list .= "      if (before) s << obj.delem;\n" unless $j == 1;
        $cus_equal_list .= "      s << obj.obj->names[".($j-1)."] << obj.comp";
        $cus_equal_list .=        " << obj.manip << obj.obj->I$j;\n";
	$cus_equal_list .= "      before = true; \n" unless $j == $i;
	$cus_equal_list .= "     } \n";

        $equal_list .= "    s << obj.obj->names[".($j-1)."] << obj.comp";
        $equal_list .= " << obj.manip << obj.obj->I$j";
	$equal_list .= " << obj.delem;\n" unless $j == $i;
        $cusparms1  .= "bool i$j"         if     $j == 1;
	$cusparms1  .= "bool i$j = false" unless $j == 1;
	$cusparms1  .= ", " unless $j == $i;
        $cusparms11  .= "bool i$j" ;
	$cusparms11  .= ", " unless $j == $i;
	$cusparms2  .= "NAME##_enum i$j" if $j == 1;
	$cusparms2  .= "NAME##_enum i$j = NAME##_NULL" unless $j == 1;
	$cusparms2  .= ", " unless $j == $i;
	$cusparms22  .= "NAME##_enum i$j";
	$cusparms22  .= ", " unless $j == $i;
        $cusparmsv  .= "i$j";
	$cusparmsv  .= ", " unless $j == $i;
	$parmC .= "T$j, I$j";
	$parmC .= ", " unless $j == $max_data_members;
        $parmc .= "I$j";
	$parmc .= ", " unless $j == $max_data_members;
    }
    foreach my $j ($i+1 .. $max_data_members) {
	$parmC .= "0, 0";
	$parmC .= ", " unless $j == $max_data_members;
        $parmc .= "0";
	$parmc .= ", " unless $j == $max_data_members;
    }

    print OUT << "---";
// ---------------------------------------------------
//                  Begin Create $i
// ---------------------------------------------------
---
    my $out = <<"---";
#define sql_create_basic_c_order_$i(NAME, CMP, CONTR, $parm_order)

  struct NAME; 

  template <mysqlpp::sql_dummy_type dummy> int sql_compare_##NAME (const NAME &, const NAME &);

  struct NAME { 
$defs 
    NAME () {} 
    NAME (const mysqlpp::Row &row);
    sql_compare_define_##CMP(NAME, $parmC)
  }; 

  template <mysqlpp::sql_dummy_type dummy> 
    void populate_##NAME (NAME *s, const mysqlpp::Row &row) { 
$popul 
  } 

  inline NAME::NAME (const mysqlpp::Row &row) 
    {populate_##NAME<mysqlpp::sql_dummy>(this, row);} 

  sql_COMPARE__##CMP(NAME, $parmc )
---
    print OUT &prepare($out);

    $out = <<"---";
#define sql_create_complete_$i(NAME, CMP, CONTR, $parm_complete) 
  struct NAME; 

  enum NAME##_enum { 
$enums 
    ,NAME##_NULL 
  }; 

  template <class Manip>
  class NAME##_value_list { 
  /*friend std::ostream& operator << <> (std::ostream&, const NAME##_value_list&); */
  public: 
    const NAME *obj;
    mysqlpp::cchar *delem;
    Manip manip;
  public: 
    NAME##_value_list (const NAME *o, mysqlpp::cchar *d, Manip m) 
      : obj(o), delem(d), manip(m) {} 
  };

  template <class Manip>
  class NAME##_##field_list {
  /* friend std::ostream& operator << <> (std::ostream&, const NAME##_field_list&); */
  public: 
    const NAME *obj; 
    mysqlpp::cchar *delem;
    Manip manip;
  public: 
    NAME##_field_list (const NAME *o, mysqlpp::cchar *d, Manip m) 
      : obj(o), delem(d), manip(m) {} 
  };

  template <class Manip>
  class NAME##_equal_list { 
  /* friend std::ostream& operator << <> (std::ostream&, const NAME##_equal_list&); */
  public: 
    const NAME *obj;
    mysqlpp::cchar *delem;
    mysqlpp::cchar *comp;
    Manip manip;
  public: 
    NAME##_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m) 
      : obj(o), delem(d), comp(c), manip(m) {}
  };

  template <class Manip>
  class NAME##_cus_value_list {
  /* friend std::ostream& operator << <> (std::ostream&, 
  				  const NAME##_cus_value_list<Manip>&); */
  public:
    const NAME *obj;
    std::vector<bool> *include;
    bool del_vector;
    mysqlpp::cchar *delem;
    Manip manip;
  public: 
    ~NAME##_cus_value_list () {if (del_vector) delete include;} 
    NAME##_cus_value_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11);
    NAME##_cus_value_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22); 
    NAME##_cus_value_list (const NAME *o, mysqlpp::cchar *d, Manip m ,std::vector<bool>* i)
      : obj(o), include(i), del_vector(false), delem(d), manip(m) {}
  };

  template <class Manip>
  class NAME##_cus_field_list { 
  /* friend std::ostream& operator << <> (std::ostream&, 
     				  const NAME##_cus_field_list<Manip>&); */
  public:
    const NAME *obj; 
    std::vector<bool> *include; 
    bool del_vector; 
    mysqlpp::cchar *delem;
    Manip manip;
  public: 
    ~NAME##_cus_field_list () {if (del_vector) delete include;} 
    NAME##_cus_field_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11); 
    NAME##_cus_field_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22); 
    NAME##_cus_field_list (const NAME *o, mysqlpp::cchar *d, Manip m, std::vector<bool> *i) 
      : obj(o), include(i), del_vector(false), delem(d), manip(m) {}
  };

 template <class Manip>
 class NAME##_cus_equal_list {
 /* friend std::ostream& operator << <> (std::ostream&, 
				  const NAME##_cus_equal_list<Manip>&); */
  public:
    const NAME *obj;
    std::vector<bool> *include;
    bool del_vector;
    mysqlpp::cchar *delem;
    mysqlpp::cchar *comp;
    Manip manip;
  public:
    ~NAME##_##cus_equal_list () {if (del_vector) delete include;}
    NAME##_##cus_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms11); 
    NAME##_##cus_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms22); 
    NAME##_##cus_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, std::vector<bool> *i) 
      : obj(o), include(i), del_vector(false), delem(d), comp(c), manip(m) {}
  };

  template <mysqlpp::sql_dummy_type dummy> int sql_compare_##NAME (const NAME &, const NAME &);

  struct NAME { 
$defs 
    NAME () {} 
    NAME (const mysqlpp::Row &row);
    void set (const mysqlpp::Row &row);
    sql_compare_define_##CMP(NAME, $parmC)
    sql_construct_define_##CONTR(NAME, $parmC)
    static const char *names[];
    static const char *_table;
    static const char *& table() {return _table;}

    NAME##_value_list<mysqlpp::quote_type0> value_list() const {
      return value_list(",", mysqlpp::quote);}
    NAME##_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d) const {
      return value_list(d, mysqlpp::quote);}
    template <class Manip> 
    NAME##_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m) const; 

    NAME##_field_list<mysqlpp::do_nothing_type0> field_list() const {
      return field_list(",", mysqlpp::do_nothing);}
    NAME##_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d) const {
      return field_list(d, mysqlpp::do_nothing);}
    template <class Manip>
    NAME##_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m) const; 

    NAME##_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d = ",", 
                                              mysqlpp::cchar *c = " = ") const{
      return equal_list(d, c, mysqlpp::quote);}
    template <class Manip>
    NAME##_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m) const; 
    
    /* cus_data */

    NAME##_cus_value_list<mysqlpp::quote_type0> value_list($cusparms1) const {
      return value_list(",", mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_value_list<mysqlpp::quote_type0> value_list($cusparms2) const {
      return value_list(",", mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_value_list<mysqlpp::quote_type0> value_list(std::vector<bool> *i) const {
      return value_list(",", mysqlpp::quote, i);
    }
    NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::sql_cmp_type sc) const {
      return value_list(",", mysqlpp::quote, sc);
    }

    NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d, $cusparms1) const {
      return value_list(d, mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d, $cusparms2) const {
      return value_list(d, mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d, 
						std::vector<bool> *i) const {
      return value_list(d, mysqlpp::quote, i);
    }
    NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d, 
						mysqlpp::sql_cmp_type sc) const {
      return value_list(d, mysqlpp::quote, sc);
    }

    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m,
					  $cusparms1) const; 
    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m,
					  $cusparms2) const; 
    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m, 
					  std::vector<bool> *i) const;
    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m, 
					  mysqlpp::sql_cmp_type sc) const;
    /* cus field */

    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list($cusparms1) const {
      return field_list(",", mysqlpp::do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list($cusparms2) const {
      return field_list(",", mysqlpp::do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(std::vector<bool> *i) const {
      return field_list(",", mysqlpp::do_nothing, i);
    }
    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::sql_cmp_type sc) const
    {
      return field_list(",", mysqlpp::do_nothing, sc);
    }

    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d, 
						       $cusparms1) const {
      return field_list(d, mysqlpp::do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d,
						       $cusparms2) const {
      return field_list(d, mysqlpp::do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d, 
						std::vector<bool> *i) const {
      return field_list(d, mysqlpp::do_nothing, i);
    }
    NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d, 
						mysqlpp::sql_cmp_type sc) const {
      return field_list(d, mysqlpp::do_nothing, sc);
    }

    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
					    $cusparms1) const; 
    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
					    $cusparms2) const; 
    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
					    std::vector<bool> *i) const;
    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m, 
					    mysqlpp::sql_cmp_type sc) const;

    /* cus equal */

    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list($cusparms1) const {
      return equal_list(",", " = ", mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list($cusparms2) const {
      return equal_list(",", " = ", mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(std::vector<bool> *i) const {
      return equal_list(",", " = ", mysqlpp::quote, i);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::sql_cmp_type sc) const {
      return equal_list(",", " = ", mysqlpp::quote, sc);
    }

    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, $cusparms1) const {
      return equal_list(d, " = ", mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, $cusparms2) const {
      return equal_list(d, " = ", mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, 
						std::vector<bool> *i) const {
      return equal_list(d, " = ", mysqlpp::quote, i);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, 
						mysqlpp::sql_cmp_type sc) const {
      return equal_list(d, " = ", mysqlpp::quote, sc);
    }

    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
                                                $cusparms1) const {
      return equal_list(d, c, mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
                                                $cusparms2) const {
      return equal_list(d, c, mysqlpp::quote, $cusparmsv);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
						std::vector<bool> *i) const {
      return equal_list(d, c, mysqlpp::quote, i);
    }
    NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
						mysqlpp::sql_cmp_type sc) const {
      return equal_list(d, c, mysqlpp::quote, sc);
    }

    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, 
					    $cusparms1) const; 
    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, 
					    $cusparms2) const; 
    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, 
					    std::vector<bool> *i) const;
    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, 
					    mysqlpp::sql_cmp_type sc) const;
  }; 
  $suppress_statics_start
  const char *NAME::names[] = { 
$names 
  }; 
  const char *NAME::_table = #NAME ;
  $suppress_statics_end

  template <class Manip>
  NAME##_cus_value_list<Manip>::NAME##_cus_value_list
  (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11) 
  { 
    delem = d;
    manip = m;
    del_vector = true;
    obj = o; 
    include = new std::vector<bool>($i, false);
$create_bool 
  } 

  template <class Manip>
  NAME##_cus_value_list<Manip>::NAME##_cus_value_list
  (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22) { 
    delem = d;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new std::vector<bool>($i, false); 
$create_list 
  }

  template <class Manip>
  NAME##_cus_field_list<Manip>::NAME##_cus_field_list
  (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11) {
    delem = d;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new std::vector<bool>($i, false); 
$create_bool 
  } 

  template <class Manip>
  NAME##_cus_field_list<Manip>::NAME##_cus_field_list
  (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22) { 
    delem = d;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new std::vector<bool>($i, false); 
$create_list 
  }

  template <class Manip>
  NAME##_cus_equal_list<Manip>::NAME##_cus_equal_list
  (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms11) { 
    delem = d;
    comp = c;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new std::vector<bool>($i, false); 
$create_bool 
  } 

  template <class Manip>
  NAME##_cus_equal_list<Manip>::NAME##_cus_equal_list
  (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms22) { 
    delem = d;
    comp = c;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new std::vector<bool>($i, false); 
$create_list 
  }

  template <class Manip>
  std::ostream& operator << (std::ostream& s, const NAME##_value_list<Manip>& obj) { 
$value_list; 
    return s; 
  } 

  template <class Manip>
  std::ostream& operator << (std::ostream& s, const NAME##_field_list<Manip>& obj) { 
$field_list; 
    return s; 
  } 

  template <class Manip>
  std::ostream& operator << (std::ostream& s, const NAME##_equal_list<Manip>& obj) { 
$equal_list; 
    return s; 
  } 

  template <class Manip>
  std::ostream& operator << (std::ostream& s, const NAME##_cus_value_list<Manip>& obj) { 
    bool before = false; 
$value_list_cus 
    return s; 
  } 

  template <class Manip>
  std::ostream& operator << (std::ostream& s, const NAME##_cus_field_list<Manip>& obj) { 
    bool before = false; 
$cus_field_list 
    return s; 
  } 

  template <class Manip>
  std::ostream& operator << (std::ostream& s, const NAME##_cus_equal_list<Manip>& obj) { 
    bool before = false; 
$cus_equal_list 
    return s; 
  } 

  template <class Manip>
  inline NAME##_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m) const { 
    return NAME##_value_list<Manip> (this, d, m); 
  } 

  template <class Manip>
  inline NAME##_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m) const { 
    return NAME##_field_list<Manip> (this, d, m); 
  } 

  template <class Manip>
  inline NAME##_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m) const { 
    return NAME##_equal_list<Manip> (this, d, c, m); 
  } 
 
  template <class Manip>
  inline NAME##_cus_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m,
						       $cusparms11) const {
    return NAME##_cus_value_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m,
							 $cusparms11) const { 
    return NAME##_cus_field_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
							 $cusparms11) const { 
    return NAME##_cus_equal_list<Manip> (this, d, c, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m,
						       $cusparms22) const { 
    return NAME##_cus_value_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m,
							 $cusparms22) const {
    return NAME##_cus_field_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, 
							 $cusparms22) const { 
    return NAME##_cus_equal_list<Manip> (this, d, c, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m,
                                                       std::vector<bool> *i) const {
    return NAME##_cus_value_list<Manip> (this, d, m, i);
  }

  template <class Manip>
  inline NAME##_cus_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m,
                                                       std::vector<bool> *i) const {
    return NAME##_cus_field_list<Manip> (this, d, m, i);
  }

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
                                                       std::vector<bool> *i) const {
    return NAME##_cus_equal_list<Manip> (this, d, c, m, i);
  }

  template <class Manip>
  inline NAME##_cus_value_list<Manip> 
  NAME::value_list(mysqlpp::cchar *d, Manip m, mysqlpp::sql_cmp_type /*sc*/) const {
    sql_compare_type_def_##CMP (NAME, value, NUM);
  }

  template <class Manip>
  inline NAME##_cus_field_list<Manip> 
  NAME::field_list(mysqlpp::cchar *d, Manip m, mysqlpp::sql_cmp_type /*sc*/) const {
    sql_compare_type_def_##CMP (NAME, field, NUM);
  }

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> 
  NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, mysqlpp::sql_cmp_type /*sc*/) const {
    sql_compare_type_defe_##CMP (NAME, equal, NUM);
  }

  template <mysqlpp::sql_dummy_type dummy> 
  void populate_##NAME (NAME *s, const mysqlpp::Row &row) { 
$popul
  } 

  inline NAME::NAME (const mysqlpp::Row &row) 
                                        {populate_##NAME<mysqlpp::sql_dummy>(this, row);}
  inline void NAME::set (const mysqlpp::Row &row)
                                        {populate_##NAME<mysqlpp::sql_dummy>(this, row);}

  sql_COMPARE__##CMP(NAME, $parmc )

---
print OUT &prepare($out);

#
# short cut defs
#

print OUT << "---";
#define sql_create_basic_$i(NAME, CMP, CONTR, $parm_simple_b) \\
  sql_create_basic_c_order_$i(NAME, CMP, CONTR, $parm_simple2c_b)

#define sql_create_$i(NAME, CMP, CONTR, $parm_simple) \\
  sql_create_complete_$i(NAME, CMP, CONTR, $parm_simple2c) \\

#define sql_create_c_order_$i(NAME, CMP, CONTR, $parm_order) \\
  sql_create_complete_$i(NAME, CMP, CONTR, $parm_order2c)

#define sql_create_c_names_$i(NAME, CMP, CONTR, $parm_names) \\
  sql_create_complete_$i(NAME, CMP, CONTR, $parm_names2c)

// ---------------------------------------------------
//                  End Create $i
// ---------------------------------------------------

---

}


sub prepare {
    local $_ = $_[0];
    s/\n+$//;
    s/\n[\n ]*\n/\n/g; 
    s/\n+/\\\n/g;
    $_ .= "\n\n";
    return $_;
}

Deleted lib/datetime.cpp.
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



























































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 datetime.cpp - Implements date and time classes compatible with MySQL's
	various date and time column types.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "datetime.h"

#include <iomanip>

#include <time.h>

using namespace std;

namespace mysqlpp {

std::ostream& operator <<(std::ostream& os, const Date& d)
{
	char fill = os.fill('0');
	ios::fmtflags flags = os.setf(ios::right);
	os		<< setw(4) << d.year << '-' 
			<< setw(2) << d.month << '-'
			<< setw(2) << d.day;
	os.flags(flags);
	os.fill(fill);
	return os;
}


std::ostream& operator <<(std::ostream& os, const Time& t)
{
	char fill = os.fill('0');
	ios::fmtflags flags = os.setf(ios::right);
	os		<< setw(2) << t.hour << ':' 
			<< setw(2) << t.minute << ':'
			<< setw(2) << t.second;
	os.flags(flags);
	os.fill(fill);
	return os;
}


std::ostream& operator <<(std::ostream& os, const DateTime& dt)
{
	operator <<(os, Date(dt));
	os << ' ';
	return operator <<(os, Time(dt));
}


cchar* Date::convert(cchar* str)
{
	char num[5];

	num[0] = *str++;
	num[1] = *str++;
	num[2] = *str++;
	num[3] = *str++;
	num[4] = 0;
	year = short(strtol(num, 0, 10));
	if (*str == '-') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	month = short(strtol(num, 0, 10));
	if (*str == '-') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	day = short(strtol(num, 0, 10));

	return str;
}


cchar* Time::convert(cchar* str)
{
	char num[5];

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	hour = short(strtol(num,0,10));
	if (*str == ':') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	minute = short(strtol(num,0,10));
	if (*str == ':') str++;

	num[0] = *str++;
	num[1] = *str++;
	num[2] = 0;
	second = short(strtol(num,0,10));

	return str;
}


cchar* DateTime::convert(cchar* str)
{
	Date d;
	str = d.convert(str);
	year = d.year;
	month = d.month;
	day = d.day;
	
	if (*str == ' ') ++str;

	Time t;
	str = t.convert(str);
	hour = t.hour;
	minute = t.minute;
	second = t.second;
	
	return str;
}


short int Date::compare(const Date& other) const
{
	if (year != other.year) return year - other.year;
	if (month != other.month) return month - other.month;
	return day - other.day;
}


short int Time::compare(const Time& other) const
{
	if (hour != other.hour) return hour - other.hour;
	if (minute != other.minute) return minute - other.minute;
	return second - other.second;
}


short int DateTime::compare(const DateTime& other) const
{
	Date d(*this), od(other);
	Time t(*this), ot(other);

	if (int x = d.compare(od)) {
		return x;
	}
	else {
		return t.compare(ot);
	}
}

DateTime::operator time_t() const
{
	struct tm tm;
	tm.tm_sec = second;
	tm.tm_min = minute;
	tm.tm_hour = hour;
	tm.tm_mday = day;
	tm.tm_mon = month - (tiny_int)1;
	tm.tm_year = year - 1900;
	tm.tm_isdst = -1;

	return mktime(&tm);
};

DateTime::DateTime(time_t t)
{
	struct tm tm;
#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(_STLP_VERSION) && \
		!defined(_STLP_VERSION_STR)
	// Use thread-safe localtime() replacement included with VS2005 and
	// up, but only when using native RTL, not STLport.
	localtime_s(&tm, &t);
#elif defined(HAVE_LOCALTIME_R)
	// Detected POSIX thread-safe localtime() replacement.
	localtime_r(&t, &tm);
#else
	// No explicitly thread-safe localtime() replacement found.  This
	// may still be thread-safe, as some C libraries take special steps
	// within localtime() to get thread safety.  For example, thread-
	// local storage (TLS) in some Windows compilers.
	memcpy(&tm, localtime(&t), sizeof(tm));
#endif

	year = tm.tm_year + 1900;
	month = tm.tm_mon + 1;
	day = tm.tm_mday;
	hour = tm.tm_hour;
	minute = tm.tm_min;
	second = tm.tm_sec;
}

} // end namespace mysqlpp


Deleted lib/datetime.h.
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
































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file datetime.h
/// \brief Declares classes to add MySQL-compatible date and time
/// types to C++'s type system.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_DATETIME_H
#define MYSQLPP_DATETIME_H

#include "common.h"

#include "coldata.h"
#include "stream2string.h"
#include "tiny_int.h"

#include <string>
#include <sstream>
#include <iostream>

namespace mysqlpp {

/// \brief Base class template for MySQL++ date and time classes.
///
/// This template primarily defines the comparison operators, which are
/// all implemented in terms of compare(). Each subclass implements that
/// as a protected method, because these operators are the only
/// supported comparison method.
///
/// This template also defines interfaces for converting the object to
/// a string form, which a subclass must define.
template <class T> struct DTbase
{
	/// \brief Destroy object
	virtual ~DTbase() { }

	/// \brief Return a copy of the item in C++ string form
	operator std::string() const
	{
		return stream2string<std::string>(*this);
	}

	/// \brief Compare this object to another of the same type
	///
	/// Returns < 0 if this object is "before" the other, 0 of they are
	/// equal, and > 0 if this object is "after" the other.
	MYSQLPP_EXPORT virtual short compare(const T& other) const = 0;

	/// \brief Returns true if "other" is equal to this object
	bool operator ==(const T& other) const
	{
		return !compare(other);
	}

	/// \brief Returns true if "other" is not equal to this object
	bool operator !=(const T& other) const
	{
		return compare(other);
	}

	/// \brief Returns true if "other" is less than this object
	bool operator <(const T& other) const
	{
		return compare(other) < 0;
	}

	/// \brief Returns true if "other" is less than or equal to this object
	bool operator <=(const T& other) const
	{
		return compare(other) <= 0;
	}

	/// \brief Returns true if "other" is greater than this object
	bool operator >(const T& other) const
	{
		return compare(other) > 0;
	}

	/// \brief Returns true if "other" is greater than or equal to this object
	bool operator >=(const T& other) const
	{
		return compare(other) >= 0;
	}
};


/// \brief C++ form of MySQL's DATETIME type.
///
/// Objects of this class can be inserted into streams, and
/// initialized from MySQL DATETIME strings.
struct DateTime : public DTbase<DateTime>
{
	/// \brief the year
	///
	/// No surprises; the year 2005 is stored as the integer 2005.
	short int year;

	/// \brief the month, 1-12
	tiny_int month;

	/// \brief the day, 1-31
	tiny_int day;

	/// \brief hour, 0-23
	tiny_int hour;

	/// \brief minute, 0-59
	tiny_int minute;
	
	/// \brief second, 0-59
	tiny_int second;

	/// \brief Default constructor
	DateTime() :
	DTbase<DateTime>(),
	year(0),
	month(0),
	day(0),
	hour(0),
	minute(0),
	second(0)
	{
	}
	
	/// \brief Initialize object as a copy of another Date
	DateTime(const DateTime& other) :
	DTbase<DateTime>(),
	year(other.year),
	month(other.month),
	day(other.day),
	hour(other.hour),
	minute(other.minute),
	second(other.second)
	{
	}

	/// \brief Initialize object from a MySQL date-and-time string
	///
	/// String must be in the HH:MM:SS format.  It doesn't have to be
	/// zero-padded.
	DateTime(cchar* str) { convert(str); }
	
	/// \brief Initialize object from a MySQL date-and-time string
	///
	/// \sa DateTime(cchar*)
	DateTime(const ColData& str)
	{
		convert(str.c_str());
	}

	/// \brief Initialize object from a MySQL date-and-time string
	///
	/// \sa DateTime(cchar*)
	DateTime(const std::string& str)
	{
		convert(str.c_str());
	}

	/// \brief Initialize object from a time_t
	DateTime(time_t t);

	/// \brief Compare this datetime to another.
	///
	/// Returns < 0 if this datetime is before the other, 0 of they are
	/// equal, and > 0 if this datetime is after the other.
	///
	/// This method is protected because it is merely the engine used
	/// by the various operators in DTbase.
	MYSQLPP_EXPORT short compare(const DateTime& other) const;

	/// \brief Parse a MySQL date and time string into this object.
	MYSQLPP_EXPORT cchar* convert(cchar*);

	/// Convert to time_t
	operator time_t() const;
};


/// \brief Inserts a DateTime object into a C++ stream in a
/// MySQL-compatible format.
///
/// The date and time are inserted into the stream, in that order,
/// with a space between them.
///
/// \param os stream to insert date and time into
/// \param dt date/time object to insert into stream
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& os,
		const DateTime& dt);


/// \brief C++ form of MySQL's DATE type.
///
/// Objects of this class can be inserted into streams, and
/// initialized from MySQL DATE strings.
struct Date : public DTbase<Date>
{
	/// \brief the year
	///
	/// No surprises; the year 2005 is stored as the integer 2005.
	short int year;

	/// \brief the month, 1-12
	tiny_int month;

	/// \brief the day, 1-31
	tiny_int day;

	/// \brief Default constructor
	Date() : year(0), month(0), day(0) { }

	/// \brief Initialize object
	Date(short int y, tiny_int m, tiny_int d) :
	DTbase<Date>(),
	year(y),
	month(m),
	day(d)
	{
	}
	
	/// \brief Initialize object as a copy of another Date
	Date(const Date& other) :
	DTbase<Date>(),
	year(other.year),
	month(other.month),
	day(other.day)
	{
	}

	/// \brief Initialize object from date part of date/time object
	Date(const DateTime& other) :
	DTbase<Date>(),
	year(other.year),
	month(other.month),
	day(other.day)
	{
	}

	/// \brief Initialize object from a MySQL date string
	///
	/// String must be in the YYYY-MM-DD format.  It doesn't have to be
	/// zero-padded.
	Date(cchar* str) { convert(str); }
	
	/// \brief Initialize object from a MySQL date string
	///
	/// \sa Date(cchar*)
	Date(const ColData& str) { convert(str.c_str()); }

	/// \brief Initialize object from a MySQL date string
	///
	/// \sa Date(cchar*)
	Date(const std::string& str)
	{
		convert(str.c_str());
	}

	/// \brief Compare this date to another.
	///
	/// Returns < 0 if this date is before the other, 0 of they are
	/// equal, and > 0 if this date is after the other.
	MYSQLPP_EXPORT short int compare(const Date& other) const;

	/// \brief Parse a MySQL date string into this object.
	MYSQLPP_EXPORT cchar* convert(cchar*);
};

/// \brief Inserts a Date object into a C++ stream
///
/// The format is YYYY-MM-DD, zero-padded.
///
/// \param os stream to insert date into
/// \param d date to insert into stream
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& os,
		const Date& d);


/// \brief C++ form of MySQL's TIME type.
///
/// Objects of this class can be inserted into streams, and
/// initialized from MySQL TIME strings.
struct Time : public DTbase<Time>
{
	/// \brief hour, 0-23
	tiny_int hour;

	/// \brief minute, 0-59
	tiny_int minute;
	
	/// \brief second, 0-59
	tiny_int second;

	/// \brief Default constructor
	Time() : hour(0), minute(0), second(0) { }

	/// \brief Initialize object
	Time(tiny_int h, tiny_int m, tiny_int s) :
	hour(h),
	minute(m),
	second(s)
	{
	}

	/// \brief Initialize object as a copy of another Time
	Time(const Time& other) :
	DTbase<Time>(),
	hour(other.hour),
	minute(other.minute),
	second(other.second)
	{
	}

	/// \brief Initialize object from time part of date/time object
	Time(const DateTime& other) :
	DTbase<Time>(),
	hour(other.hour),
	minute(other.minute),
	second(other.second)
	{
	}

	/// \brief Initialize object from a MySQL time string
	///
	/// String must be in the HH:MM:SS format.  It doesn't have to be
	/// zero-padded.
	Time(cchar* str) { convert(str); }

	/// \brief Initialize object from a MySQL time string
	///
	/// \sa Time(cchar*)
	Time(const ColData& str) { convert(str.c_str()); }

	/// \brief Initialize object from a MySQL time string
	///
	/// \sa Time(cchar*)
	Time(const std::string& str)
	{
		convert(str.c_str());
	}

	/// \brief Parse a MySQL time string into this object.
	MYSQLPP_EXPORT cchar* convert(cchar*);

	/// \brief Compare this time to another.
	///
	/// Returns < 0 if this time is before the other, 0 of they are
	/// equal, and > 0 if this time is after the other.
	MYSQLPP_EXPORT short int compare(const Time& other) const;
};

/// \brief Inserts a Time object into a C++ stream in a MySQL-compatible
/// format.
///
/// The format is HH:MM:SS, zero-padded.
///
/// \param os stream to insert time into
/// \param t time to insert into stream
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& os,
		const Time& t);


} // end namespace mysqlpp

#endif // !defined(MYSQLPP_DATETIME_H)
Deleted lib/exceptions.h.
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


































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file exceptions.h
/// \brief Declares the MySQL++-specific exception classes.
///
/// When exceptions are enabled for a given mysqlpp::OptionalExceptions
/// derivative, any of these exceptions can be thrown on error.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_EXCEPTIONS_H
#define MYSQLPP_EXCEPTIONS_H

#include "connection.h"

#include <exception>
#include <string>

namespace mysqlpp {

/// \brief Base class for all MySQL++ custom exceptions

class MYSQLPP_EXPORT Exception : public std::exception
{
public:
	/// \brief Create exception object as copy of another
	Exception(const Exception& e) throw() :
	std::exception(e),
	what_(e.what_)
	{
	}

	/// \brief Assign another exception object's contents to this one
	Exception& operator=(const Exception& rhs) throw()
	{
		what_ = rhs.what_;
		return *this;
	}

	/// \brief Destroy exception object
	~Exception() throw() { }

	/// \brief Returns explanation of why exception was thrown
	virtual const char* what() const throw()
	{
		return what_.c_str();
	}

protected:
	/// \brief Create exception object
	Exception(const char* w = "") throw() :
	what_(w)
	{
	}

	/// \brief Create exception object
	Exception(const std::string& w) throw() :
	what_(w)
	{
	}

	/// \brief explanation of why exception was thrown
	std::string what_;
};


/// \brief Exception thrown when a bad type conversion is attempted.

class MYSQLPP_EXPORT BadConversion : public Exception
{
public:
	const char* type_name;	///< name of type we tried to convert to
	std::string data;		///< string form of data we tried to convert
	size_t retrieved;		///< documentation needed!
	size_t actual_size;		///< documentation needed!

	/// \brief Create exception object, building error string
	/// dynamically
	///
	/// \param tn type name we tried to convert to
	/// \param d string form of data we tried to convert
	/// \param r ??
	/// \param a ??
	BadConversion(const char* tn, const char* d,
			size_t r, size_t a) :
	Exception("Bad type conversion: \""),
	type_name(tn),
	data(d),
	retrieved(r),
	actual_size(a)
	{
		what_ += d ? d : "<NULL>";
		what_ += "\" incompatible with \"";
		what_ += tn;
		what_ += "\" type";
	}

	/// \brief Create exception object, given completed error string
	///
	/// \param w the "what" error string
	/// \param tn type name we tried to convert to
	/// \param d string form of data we tried to convert
	/// \param r ??
	/// \param a ??
	BadConversion(const std::string& w, const char* tn,
				  const char* d, size_t r, size_t a) :
	Exception(w),
	type_name(tn),
	data(d),
	retrieved(r),
	actual_size(a)
	{
	}

	/// \brief Create exception object, with error string only
	///
	/// \param w the "what" error string
	///
	/// All other data members are initialize to default values
	explicit BadConversion(const char* w = "") :
	Exception(w),
	type_name("unknown"),
	data(""),
	retrieved(0),
	actual_size(0)
	{
	}

	/// \brief Destroy exception
	~BadConversion() throw() { }
};


/// \brief Exception thrown when a requested named field doesn't exist.
///
/// Thrown by Row::lookup_by_name() when you pass a field name that
/// isn't in the result set.

class MYSQLPP_EXPORT BadFieldName : public Exception
{
public:
	/// \brief Create exception object
	///
	/// \param bad_field name of field the MySQL server didn't like
	explicit BadFieldName(const char* bad_field) :
	Exception(std::string("Unknown field name: ") + bad_field)
	{
	}

	/// \brief Destroy exception
	~BadFieldName() throw() { }
};


/// \brief Exception thrown when you attempt to convert a SQL null
/// to an incompatible type.

class MYSQLPP_EXPORT BadNullConversion : public Exception
{
public:
	/// \brief Create exception object
	explicit BadNullConversion(const char* w = "") :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when you pass an unrecognized option to
/// Connection::set_option().

class MYSQLPP_EXPORT BadOption : public Exception
{
public:
	/// \brief Create exception object, taking C string
	explicit BadOption(const char* w,
			Connection::Option o) :
	Exception(w),
	option_(o)
	{
	}

	/// \brief Create exception object, taking C++ string
	explicit BadOption(const std::string& w,
			Connection::Option o) :
	Exception(w),
	option_(o)
	{
	}

	/// \brief Return the option that failed
	Connection::Option what_option() const { return option_; }

private:
	Connection::Option option_;
};


/// \brief Exception thrown when not enough query parameters are
/// provided.
///
/// This is used in handling template queries.

class MYSQLPP_EXPORT BadParamCount : public Exception
{
public:
	/// \brief Create exception object
	explicit BadParamCount(const char* w = "") :
	Exception(w)
	{
	}

	/// \brief Destroy exception
	~BadParamCount() throw() { }
};


/// \brief Exception thrown when MySQL encounters a problem while
/// processing your query.
///
/// This exception is typically only thrown when the server rejects a
/// SQL query.  In v1.7, it was used as a more generic exception type,
/// for no particularly good reason.

class MYSQLPP_EXPORT BadQuery : public Exception
{
public:
	/// \brief Create exception object, taking C string
	explicit BadQuery(const char* w = "") :
	Exception(w)
	{
	}

	/// \brief Create exception object, taking C++ string
	explicit BadQuery(const std::string& w) :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when there is a problem establishing the
/// database server connection.  It's also thrown if
/// Connection::shutdown() fails.

class MYSQLPP_EXPORT ConnectionFailed : public Exception
{
public:
	/// \brief Create exception object
	explicit ConnectionFailed(const char* w = "") :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when the program tries to select a new
/// database and the server refuses for some reason.

class MYSQLPP_EXPORT DBSelectionFailed : public Exception
{
public:
	/// \brief Create exception object
	explicit DBSelectionFailed(const char* w = "") :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when ResUse::fetch_row() walks off the end
/// of a use-query's result set.

class MYSQLPP_EXPORT EndOfResults : public Exception
{
public:
	/// \brief Create exception object
	explicit EndOfResults(const char* w = "end of results") :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when Query::store_next() walks off the end
/// of a use-query's multi result sets.

class MYSQLPP_EXPORT EndOfResultSets : public Exception
{
public:
	/// \brief Create exception object
	explicit EndOfResultSets(const char* w = "end of result sets") :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when a Lockable object fails.
///
/// Currently, "failure" means that the object is already locked when
/// you make a call that tries to lock it again.  In the future, that
/// case will probably result in the second thread blocking, but the
/// thread library could assert other errors that would keep this
/// exception relevant.

class MYSQLPP_EXPORT LockFailed : public Exception
{
public:
	/// \brief Create exception object
	explicit LockFailed(const char* w = "lock failed") :
	Exception(w)
	{
	}
};


/// \brief Exception thrown when you try to use an object that isn't
/// completely initialized.

class MYSQLPP_EXPORT ObjectNotInitialized : public Exception
{
public:
	/// \brief Create exception object
	explicit ObjectNotInitialized(const char* w = "") :
	Exception(w)
	{
	}
};


} // end namespace mysqlpp

#endif
Deleted lib/field_names.cpp.
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
















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 field_names.cpp - Implements the FieldNames class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "field_names.h"

#include "result.h"

namespace mysqlpp {

void FieldNames::init(const ResUse * res)
{
	int num = res->num_fields();
	reserve(num);

	for (int i = 0; i < num; i++) {
		std::string p(res->fields().at(i).name);
		str_to_lwr(p);
		push_back(p);
	}
}

} // end namespace mysqlpp
Deleted lib/field_names.h.
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









































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file field_names.h
/// \brief Declares a class to hold a list of field names.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_FIELD_NAMES_H
#define MYSQLPP_FIELD_NAMES_H

#include "coldata.h"
#include "string_util.h"

#include <algorithm>
#include <vector>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT ResUse;
#endif

/// \brief Holds a list of SQL field names
class FieldNames : public std::vector<std::string>
{
public:
	/// \brief Default constructor
	FieldNames() { }
	
	/// \brief Create field name list from a result set
	FieldNames(const ResUse* res)
	{
		init(res);
	}

	/// \brief Create empty field name list, reserving space for
	/// a fixed number of field names.
	FieldNames(int i) :
	std::vector<std::string>(i)
	{
	}

	/// \brief Initializes the field list from a result set
	FieldNames& operator =(const ResUse* res)
	{
		init(res);
		return *this;
	}

	/// \brief Insert \c i empty field names at beginning of list
	FieldNames& operator =(int i)
	{
		insert(begin(), i, "");
		return *this;
	}

	/// \brief Get the name of a field given its index.
	std::string& operator [](int i)
	{
		return at(i);
	}

	/// \brief Get the name of a field given its index, in const
	/// context.
	const std::string& operator [](int i) const
	{
		return at(i);
	}

	/// \brief Get the index number of a field given its name
	uint operator [](std::string i) const
	{
		std::string temp(i);
		str_to_lwr(temp);
		return uint(std::find(begin(), end(), temp) - begin());
	}

private:
	void init(const ResUse* res);
};

} // end namespace mysqlpp

#endif
Deleted lib/field_types.cpp.
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













































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 field_types.cpp - Implements the FieldTypes class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "field_types.h"

#include "result.h"

namespace mysqlpp {

void FieldTypes::init(const ResUse * res)
{
	int num = res->num_fields();
	reserve(num);
	for (int i = 0; i < num; i++) {
		push_back(res->fields(i));
	}
}

} // end namespace mysqlpp
Deleted lib/field_types.h.
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

































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file field_types.h
/// \brief Declares a class to hold a list of SQL field type info.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_FIELD_TYPES_H
#define MYSQLPP_FIELD_TYPES_H

#include "type_info.h"

#include <vector>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT ResUse;
#endif

/// \brief A vector of SQL field types.
class FieldTypes : public std::vector<mysql_type_info>
{
public:
	/// \brief Default constructor
	FieldTypes() { }
	
	/// \brief Create list of field types from a result set
	FieldTypes(const ResUse* res)
	{
		init(res);
	}

	/// \brief Create fixed-size list of uninitialized field types
	FieldTypes(int i) :
	std::vector<mysql_type_info>(i)
	{
	}

	/// \brief Initialize field list based on a result set
	FieldTypes& operator =(const ResUse* res)
	{
		init(res);
		return *this;
	}

	/// \brief Insert a given number of uninitialized field type
	/// objects at the beginning of the list
	///
	/// \param i number of field type objects to insert
	FieldTypes& operator =(int i)
	{
		insert(begin(), i, mysql_type_info());
		return *this;
	}

	/// \brief Returns a field type within the list given its index.
	mysql_type_info& operator [](int i)
	{
		return std::vector<mysql_type_info>::operator [](i);
	}

	/// \brief Returns a field type within the list given its index,
	/// in const context.
	const mysql_type_info& operator [](int i) const
	{
		return std::vector<mysql_type_info>::operator [](i);
	}

private:
	void init(const ResUse* res);
};

} // end namespace mysqlpp

#endif
Deleted lib/fields.cpp.
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












































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 fields.cpp - Implements the Fields class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "fields.h"

#include "result.h"

namespace mysqlpp {

Fields::size_type Fields::size() const
{
	return res_->num_fields();
}

const Field& Fields::at(Fields::size_type i) const
{
	res_->field_seek(i);
	return res_->fetch_field();
}

} // end namespace mysqlpp
Deleted lib/fields.h.
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









































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file fields.h
/// \brief Declares a class for holding information about a set of
/// fields.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_FIELDS_H
#define MYSQLPP_FIELDS_H

#include "resiter.h"

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT ResUse;
#endif

/// \brief A container similar to \c std::vector for holding
/// mysqlpp::Field records.

class MYSQLPP_EXPORT Fields : public const_subscript_container<Fields, Field>
{
public:
	/// \brief Default constructor
	Fields() { }
	
	/// \brief Create a field list from a result set
	Fields(ResUse* r) :
	res_(r)
	{
	}

	/// \brief Returns a field given its index.
	const Field& at(Fields::size_type i) const;

	/// \brief Returns a field given its index.
	const Field& at(int i) const
	{
		return at(static_cast<size_type>(i));
	}

	size_type size() const;	///< get the number of fields

private:
	mutable ResUse* res_;
};

} // end namespace mysqlpp

#endif
Deleted lib/lockable.h.
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



































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file lockable.h
/// \brief Declares interface that allows a class to declare itself as
/// "lockable".
///
/// The meaning of a class being lockable is very much per-class
/// specific in this version of MySQL++.  In a future version, it will
/// imply that operations that aren't normally thread-safe will use
/// platform mutexes if MySQL++ is configured to support them.  This is
/// planned for a version beyond v2.0. (See the Wishlist for the plan.)
/// In the meantime, do not depend on this mechanism for thread safety;
/// you will have to serialize access to some resources yourself.
///
/// To effect this variability in what it means for an object to be
/// "locked", Lockable is only an interface.  It delegates the actual
/// implementation to a subclass of the Lock interface, using the
/// Bridge pattern.  (See Gamma et al.)

/***********************************************************************
 Copyright (c) 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_LOCKABLE_H
#define MYSQLPP_LOCKABLE_H

namespace mysqlpp {

/// \brief Abstract base class for lock implementation, used by
/// Lockable.

class MYSQLPP_EXPORT Lock
{
public:
	/// \brief Destroy object
	virtual ~Lock() { }

	/// \brief Lock the object
	///
	/// \return true if object was already locked
	virtual bool lock() = 0;

	/// \brief Unlock the object
	virtual void unlock() = 0;

	/// \brief Returns true if object is locked
	virtual bool locked() const = 0;

	/// \brief Set the lock state.
	virtual void set(bool b) = 0;
};


/// \brief Trivial Lock subclass, using a boolean variable as the
/// lock flag.
///
/// This is the only Lock implementation available in this version of
/// MySQL++.  It will be supplemented with a better implementation for
/// use with threads at a later date.

class MYSQLPP_EXPORT BasicLock : public Lock
{
public:
	/// \brief Create object
	BasicLock(bool is_locked = false) :
	locked_(is_locked)
	{
	}
	
	/// \brief Destroy object
	~BasicLock() { }

	/// \brief Lock the object
	///
	/// \return true if object was already locked
	bool lock()
	{
		if (locked_) {
			return true;
		}
		locked_ = true;
		return false;
	}

	/// \brief Unlock the object
	void unlock() { locked_ = false; }

	/// \brief Returns true if object is locked
	bool locked() const { return locked_; }

	/// \brief Set the lock state.
	void set(bool b) { locked_ = b; }

private:
	bool locked_;
};


/// \brief Interface allowing a class to declare itself as "lockable".
///
/// A class derives from this one to acquire a standard interface for
/// serializing operations that may not be thread-safe.

class MYSQLPP_EXPORT Lockable
{
protected:
	/// \brief Default constructor
	Lockable(bool is_locked) :
	pimpl_(new BasicLock(is_locked))
	{
	}

	/// \brief Destroy object
	virtual ~Lockable()
	{
		delete pimpl_;
	}

	/// \brief Lock the object
	///
	/// \return true if object was already locked
	virtual bool lock() { return pimpl_->lock(); }

	/// \brief Unlock the object
	virtual void unlock() { pimpl_->unlock(); }

	/// \brief Returns true if object is locked
	bool locked() const { return pimpl_->locked(); }

protected:
	/// \brief Set the lock state.  Protected, because this method is
	/// only for use by subclass assignment operators and the like.
	void set_lock(bool b) { pimpl_->set(b); }

private:
	// Don't allow default construction
	Lockable();

	// Pointer to implementation object
	Lock* pimpl_;
};

} // end namespace mysqlpp

#endif // MYSQLPP_LOCKABLE_H

Deleted lib/manip.cpp.
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


































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 manip.cpp - Implements MySQL++'s various quoting/escaping stream
	manipulators.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "manip.h"

#include "query.h"

using namespace std;

// Manipulator stuff is _always_ in namespace mysqlpp.
namespace mysqlpp {

/// \brief Set to true if you want to suppress automatic quoting
///
/// Works only for ColData inserted into C++ streams.

bool dont_quote_auto = false;


/// \brief Inserts a SQLString into a stream, quoted and escaped.
///
/// If in.is_string is set and in.dont_escape is \e not set, the string
/// is quoted and escaped.
///
/// If both in.is_string and in.dont_escape are set, the string is
/// quoted but not escaped.
///
/// If in.is_string is not set, the data is inserted as-is.  This is
/// the case when you initialize SQLString with one of the constructors
/// taking an integral type, for instance.

SQLQueryParms& operator <<(quote_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2('\'');
		if (in.dont_escape) {
			in2 += in;
			in2 += '\'';
			in2.processed = true;
			return *p.qparms << in2;
		}
		else {
			char* s = new char[in.length() * 2 + 1];
			size_t len = mysql_escape_string(s, in.data(), in.length());
			in2.append(s, len);
			in2 += '\'';
			in2.processed = true;
			*p.qparms << in2;
			delete[] s;
			return *p.qparms;
		}
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}


/// \brief Inserts a C++ string into a stream, quoted and escaped
///
/// Because std::string lacks the type information we need, the string
/// is both quoted and escaped, always.

template <>
ostream& operator <<(quote_type1 o, const string& in)
{
	char* s = new char[in.length() * 2 + 1];
	size_t len = mysql_escape_string(s, in.data(), in.length());

	o.ostr->write("'", 1);
	o.ostr->write(s, len);
	o.ostr->write("'", 1);

	delete[] s;
	return *o.ostr;
}


/// \brief Inserts a C string into a stream, quoted and escaped
///
/// Because C strings lack the type information we need, the string
/// is both quoted and escaped, always.

template <>
ostream& operator <<(quote_type1 o, const char* const& in)
{
	size_t len = strlen(in);
	char* s = new char[len * 2 + 1];
	len = mysql_escape_string(s, in, len);

	o.ostr->write("'", 1);
	o.ostr->write(s, len);
	o.ostr->write("'", 1);

	delete[] s;
	return *o.ostr;
}


/// \brief Utility function used by operator<<(quote_type1, ColData)

template<class Str>
inline ostream& _manip(quote_type1 o, const ColData_Tmpl<Str>& in)
{
	if (in.escape_q()) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());

		if (in.quote_q()) o.ostr->write("'", 1);
		o.ostr->write(s, len);
		if (in.quote_q()) o.ostr->write("'", 1);

		delete[] s;
	}
	else {
		if (in.quote_q()) o.ostr->write("'", 1);
		o.ostr->write(in.data(), in.length());
		if (in.quote_q()) o.ostr->write("'", 1);
	}

	return *o.ostr;
}


/// \brief Inserts a ColData into a stream, quoted and escaped
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to actually quote or escape the data, if it is not
/// needed.

template <>
ostream& operator <<(quote_type1 o, const ColData_Tmpl<string>& in)
{
	return _manip(o, in);
}


/// \brief Inserts a ColData with const string into a stream, quoted and
/// escaped
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to actually quote or escape the data, if it is not
/// needed.

template <>
ostream& operator <<(quote_type1 o, const ColData_Tmpl<const_string>& in)
{
	return _manip(o, in);
}


/// \brief Inserts a ColData into a stream.
///
/// Because ColData was designed to contain MySQL type data, this
/// operator has the information needed to choose to quote and/or escape
/// the data as it is inserted into the stream, even if you don't use
/// any of the quoting or escaping manipulators.

ostream& operator <<(ostream& o, const ColData_Tmpl<string>& in)
{
	// Decide if we're allowed to escape or quote the data.
	bool transform_ok =
			!dont_quote_auto &&
			(o.rdbuf() != cout.rdbuf()) &&
			(o.rdbuf() != cerr.rdbuf());

	if (transform_ok && in.escape_q()) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());

		if (in.quote_q()) o << '\'';
		o.write(s, len);
		if (in.quote_q()) o << '\'';

		delete[] s;
	}
	else {
		bool add_quote = transform_ok && in.quote_q();

		if (add_quote) o << '\'';
		o.write(in.data(), in.length());
		if (add_quote) o << '\'';
	}

	return o;
}


/// \brief Inserts a ColData with const string into a stream.
///
/// Because ColData was designed to contain MySQL type data, this
/// operator has the information needed to choose to quote and/or escape
/// the data as it is inserted into the stream, even if you don't use
/// any of the quoting or escaping manipulators.

ostream& operator <<(ostream& o, const ColData_Tmpl<const_string>& in)
{
	// Decide if we're allowed to escape or quote the data.
	bool transform_ok =
			!dont_quote_auto &&
			(o.rdbuf() != cout.rdbuf()) &&
			(o.rdbuf() != cerr.rdbuf());

	if (transform_ok && in.escape_q()) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());

		if (in.quote_q()) o << '\'';
		o.write(s, len);
		if (in.quote_q()) o << '\'';

		delete[] s;
	}
	else {
		bool add_quote = transform_ok && in.quote_q();

		if (add_quote) o << '\'';
		o.write(in.data(), in.length());
		if (add_quote) o << '\'';
	}

	return o;
}


/// \brief Insert a ColData into a SQLQuery
///
/// This operator appears to be a workaround for a weakness in one
/// compiler's implementation of the C++ type system.  See Wishlist for
/// current plan on what to do about this.

Query& operator <<(Query& o, const ColData_Tmpl<string>& in)
{
	if (dont_quote_auto) {
		o.write(in.data(), in.length());
	}
	else if (in.escape_q()) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());

		if (in.quote_q()) o.write("'", 1);
		o.write(s, len);
		if (in.quote_q()) o.write("'", 1);

		delete[] s;
	}
	else {
		if (in.quote_q()) o.write("'", 1);
		o.write(in.data(), in.length());
		if (in.quote_q()) o.write("'", 1);
	}

	return o;
}


/// \brief Insert a ColData with const string into a SQLQuery
///
/// This operator appears to be a workaround for a weakness in one
/// compiler's implementation of the C++ type system.  See Wishlist for
/// current plan on what to do about this.

Query& operator <<(Query& o, const ColData_Tmpl<const_string>& in)
{
	if (dont_quote_auto) {
		o.write(in.data(), in.length());
	}
	else if (in.escape_q()) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());

		if (in.quote_q()) o.write("'", 1);
		o.write(s, len);
		if (in.quote_q()) o.write("'", 1);

		delete[] s;
	}
	else {
		if (in.quote_q()) o.write("'", 1);
		o.write(in.data(), in.length());
		if (in.quote_q()) o.write("'", 1);
	}

	return o;
}


/// \brief Inserts a SQLString into a stream, quoting it unless it's
/// data that needs no quoting.
///
/// We make the decision to quote the data based on the in.is_string
/// flag.  You can set it yourself, but SQLString's ctors should set
/// it correctly for you.

SQLQueryParms& operator <<(quote_only_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2;
		in2 = '\'' + in + '\'';
		in2.processed = true;
		return *p.qparms << in2;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}


/// \brief Inserts a ColData into a stream, quoted
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to actually quote the data, if it is not needed.

template <>
ostream& operator <<(quote_only_type1 o, const ColData_Tmpl<string>& in)
{
	if (in.quote_q()) o.ostr->write("'", 1);
	o.ostr->write(in.data(), in.length());
	if (in.quote_q()) o.ostr->write("'", 1);

	return *o.ostr;
}


/// \brief Inserts a ColData with const string into a stream, quoted
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to actually quote the data, if it is not needed.

template <>
ostream& operator <<(quote_only_type1 o,
		const ColData_Tmpl<const_string>& in)
{
	if (in.quote_q()) o.ostr->write("'", 1);
	o.ostr->write(in.data(), in.length());
	if (in.quote_q()) o.ostr->write("'", 1);

	return *o.ostr;
}


/// \brief Inserts a SQLString into a stream, double-quoting it (")
/// unless it's data that needs no quoting.
///
/// We make the decision to quote the data based on the in.is_string
/// flag.  You can set it yourself, but SQLString's ctors should set
/// it correctly for you.

SQLQueryParms& operator <<(quote_double_only_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2;
		in2 = "\"" + in + "\"";
		in2.processed = true;
		return *p.qparms << in2;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}


/// \brief Inserts a ColData into a stream, double-quoted (")
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to actually quote the data, if it is not needed.

template <>
ostream& operator <<(quote_double_only_type1 o,
		const ColData_Tmpl<string>& in)
{
	if (in.quote_q()) o.ostr->write("\"", 1);
	o.ostr->write(in.data(), in.length());
	if (in.quote_q()) o.ostr->write("\"", 1);

	return *o.ostr;
}


/// \brief Inserts a ColData with const string into a stream,
/// double-quoted (")
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to actually quote the data, if it is not needed.

template <>
ostream& operator <<(quote_double_only_type1 o,
		const ColData_Tmpl<const_string>& in)
{
	if (in.quote_q()) o.ostr->write("'", 1);
	o.ostr->write(in.data(), in.length());
	if (in.quote_q()) o.ostr->write("'", 1);

	return *o.ostr;
}


SQLQueryParms& operator <<(escape_type2 p, SQLString& in)
{
	if (in.is_string && !in.dont_escape) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());

		SQLString in2(s, len);
		in2.processed = true;
		*p.qparms << in2;

		delete[] s;
		return *p.qparms;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}


/// \brief Inserts a C++ string into a stream, escaping special SQL
/// characters
///
/// Because std::string lacks the type information we need, the string
/// is always escaped, even if it doesn't need it.

template <>
std::ostream& operator <<(escape_type1 o, const std::string& in)
{
	char* s = new char[in.length() * 2 + 1];
	size_t len = mysql_escape_string(s, in.data(), in.length());
	o.ostr->write(s, len);
	delete[] s;
	return *o.ostr;
}


/// \brief Inserts a C string into a stream, escaping special SQL
/// characters
///
/// Because C's type system lacks the information we need to second-
/// guess this manipulator, we always run the escaping algorithm on
/// the data, even if it's not needed.

template <>
ostream& operator <<(escape_type1 o, const char* const& in)
{
	size_t len = strlen(in);
	char* s = new char[len * 2 + 1];
	len = mysql_escape_string(s, in, len);
	o.ostr->write(s, len);
	delete[] s;
	return *o.ostr;
}


/// \brief Utility function used by operator<<(escape_type1, ColData)

template <class Str>
inline ostream& _manip(escape_type1 o, const ColData_Tmpl<Str>& in)
{
	if (in.escape_q()) {
		char* s = new char[in.length() * 2 + 1];
		size_t len = mysql_escape_string(s, in.data(), in.length());
		o.ostr->write(s, len);
		delete[] s;
	}
	else {
		o.ostr->write(in.data(), in.length());
	}

	return *o.ostr;
}


/// \brief Inserts a ColData into a stream, escaping special SQL
/// characters
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to escape the data, if it is not needed.

template <>
std::ostream& operator <<(escape_type1 o,
		const ColData_Tmpl<std::string>& in)
{
	return _manip(o, in);
}


/// \brief Inserts a ColData with const string into a stream, escaping
/// special SQL characters
///
/// Because ColData was designed to contain MySQL type data, we may
/// choose not to escape the data, if it is not needed.

template <>
std::ostream& operator <<(escape_type1 o, const ColData_Tmpl<const_string>& in)
{
	return _manip(o, in);
}


/// \brief Inserts a SQLString into a stream, with no escaping or
/// quoting.

SQLQueryParms& operator <<(do_nothing_type2 p, SQLString& in)
{
	in.processed = true;
	return *p.qparms << in;
}


/// \brief Inserts a SQLString into a stream, with no escaping or
/// quoting, and without marking the string as having been "processed".

SQLQueryParms& operator <<(ignore_type2 p, SQLString& in)
{
	return *p.qparms << in;
}

} // end namespace mysqlpp

Deleted lib/manip.h.
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








































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file manip.h
/// \brief Declares \c std::ostream manipulators useful with SQL syntax.
///
/// These manipulators let you automatically quote elements or escape
/// characters that are special in SQL when inserting them into an
/// \c std::ostream. Since mysqlpp::Query is an ostream, these
/// manipulators make it easier to build syntactically-correct SQL
/// queries.
///
/// This file also includes \c operator<< definitions for ColData_Tmpl,
/// one of the MySQL++ string-like classes.  When inserting such items
/// into a stream, they are automatically quoted and escaped as
/// necessary unless the global variable dont_quote_auto is set to true.
/// These operators are smart enough to turn this behavior off when
/// the stream is \c cout or \c cerr, however, since quoting and
/// escaping are surely not required in that instance.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_MANIP_H
#define MYSQLPP_MANIP_H

#include "common.h"

#include "datetime.h"
#include "myset.h"
#include "sql_string.h"

#include <iostream>

/// All global symbols in MySQL++ are in namespace mysqlpp.  This is
/// needed because many symbols are rather generic (e.g. Row, Query...),
/// so there is a serious danger of conflicts.
namespace mysqlpp {

class Query;

extern bool dont_quote_auto;


/// \enum quote_type0
/// \anchor quote_manip
///
/// The standard 'quote' manipulator.
///
/// Insert this into a stream to put single quotes around the next item
/// in the stream, and escape characters within it that are 'special'
/// in SQL.  This is the most generally useful of the manipulators.


enum quote_type0
{
	quote					///< insert into a std::ostream to single-quote and escape next item
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

struct quote_type1
{
	std::ostream * ostr;
	quote_type1(std::ostream * o) :
	ostr(o)
	{
	}
};


inline quote_type1 operator <<(std::ostream& o,
		quote_type0 /*esc */)
{
	return quote_type1(&o);
}


class SQLQueryParms;
struct quote_type2
{
	SQLQueryParms *qparms;
	quote_type2(SQLQueryParms* p) :
	qparms(p)
	{
	}
};


inline quote_type2 operator <<(SQLQueryParms& p,
		quote_type0 /*esc */)
{
	return quote_type2(&p);
}


MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_type2 p,
		SQLString& in);


template <class T>
inline std::ostream& operator <<(quote_type1 o, const T & in)
{
	return *o.ostr << in;
}


MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
		const ColData_Tmpl<std::string>& in);


MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
		const ColData_Tmpl<const_string>& in);


MYSQLPP_EXPORT Query& operator <<(Query& o,
		const ColData_Tmpl<std::string>& in);


MYSQLPP_EXPORT Query& operator <<(Query& o,
		const ColData_Tmpl<const_string>& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
		const std::string& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
		const char* const& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
		const ColData_Tmpl<std::string>& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
		const ColData_Tmpl<const_string>& in);


template <>
inline std::ostream& operator <<(quote_type1 o,
		char* const& in)
{
	return operator <<(o, const_cast<const char* const&>(in));
}

inline std::ostream& operator <<(quote_type1 o,
		char in[])
{
	return operator <<(o, static_cast<const char* const&>(in));
}

inline std::ostream& operator <<(quote_type1 o,
		const char in[])
{
	return operator <<(o, const_cast<char* const&>(in));
}


template <>
inline std::ostream& operator <<(quote_type1 o,
		const Date& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <>
inline std::ostream& operator <<(quote_type1 o,
		const Time& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <>
inline std::ostream& operator <<(quote_type1 o,
		const DateTime& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <class ST>
inline std::ostream& operator <<(quote_type1 o, const Set<ST>& in)
{
	return *o.ostr << '\'' << in << '\'';
}

#endif // !defined(DOXYGEN_IGNORE)


/// \enum quote_only_type0
/// \anchor quote_only_manip
///
/// The 'quote_only' manipulator.
///
/// Similar to <a href="#quote_manip">quote manipulator</a>, except that
/// it doesn't escape special SQL characters.

enum quote_only_type0
{
	quote_only				///< insert into a std::ostream to single-quote next item
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

struct quote_only_type1
{
	std::ostream* ostr;
	quote_only_type1(std::ostream* o) :
	ostr(o)
	{
	}
};


inline quote_only_type1 operator <<(std::ostream& o,
		quote_only_type0 /* esc */)
{
	return quote_only_type1(&o);
}


struct quote_only_type2
{
	SQLQueryParms* qparms;
	quote_only_type2(SQLQueryParms* p) :
	qparms(p)
	{
	}
};


inline quote_only_type2 operator <<(SQLQueryParms& p,
		quote_only_type0 /* esc */)
{
	return quote_only_type2(&p);
}

MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_only_type2 p,
		SQLString& in);


template <class T>
inline std::ostream& operator <<(quote_only_type1 o, const T& in)
{
	return *o.ostr << in;
}


template <>
inline std::ostream& operator <<(quote_only_type1 o,
		const std::string& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_only_type1 o,
		const ColData_Tmpl<std::string>& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_only_type1 o,
		const ColData_Tmpl<const_string>& in);


template <>
inline std::ostream& operator <<(quote_only_type1 o,
		const Date& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <>
inline std::ostream& operator <<(quote_only_type1 o,
		const Time& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <>
inline std::ostream& operator <<(quote_only_type1 o,
		const DateTime& in)
{
	return *o.ostr << '\'' << in << '\'';
}


template <class ST>
inline std::ostream& operator <<(quote_only_type1 o, const Set<ST>& in)
{
	return *o.ostr << '\'' << in << '\'';
}

#endif // !defined(DOXYGEN_IGNORE)


/// \enum quote_double_only_type0
/// \anchor quote_double_manip
///
/// The 'double_quote_only' manipulator.
///
/// Similar to <a href="#quote_only_manip">quote_only manipulator</a>,
/// except that it uses double quotes instead of single quotes.

enum quote_double_only_type0
{
	quote_double_only		///< insert into a std::ostream to double-quote next item
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

struct quote_double_only_type1
{
	std::ostream* ostr;
	quote_double_only_type1(std::ostream* o) :
	ostr(o)
	{
	}
};


inline quote_double_only_type1 operator <<(
		std::ostream& o, quote_double_only_type0 /* esc */)
{
	return quote_double_only_type1(&o);
}


struct quote_double_only_type2
{
	SQLQueryParms *qparms;
	quote_double_only_type2(SQLQueryParms* p) :
	qparms(p)
	{
	}
};


inline quote_double_only_type2 operator <<(
		SQLQueryParms& p, quote_double_only_type0 /* esc */)
{
	return quote_double_only_type2(&p);
}


MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_double_only_type2 p,
		SQLString& in);


template <class T>
inline std::ostream& operator <<(quote_double_only_type1 o, const T& in)
{
	return *o.ostr << in;
}


template <>
inline std::ostream& operator <<(
		quote_double_only_type1 o, const std::string& in)
{
	return *o.ostr << '"' << in << '"';
}


template <>
MYSQLPP_EXPORT std::ostream& operator <<(quote_double_only_type1 o,
		const ColData_Tmpl<std::string>& in);


template <>
MYSQLPP_EXPORT std::ostream & operator <<(quote_double_only_type1 o,
		const ColData_Tmpl<const_string>& in);


template <>
inline std::ostream& operator <<(
		quote_double_only_type1 o, const Date& in)
{
	return *o.ostr << '"' << in << '"';
}


template <>
inline std::ostream& operator <<(
		quote_double_only_type1 o, const Time& in)
{
	return *o.ostr << '"' << in << '"';
}


template <>
inline std::ostream& operator <<(
		quote_double_only_type1 o, const DateTime& in)
{
	return *o.ostr << '"' << in << '"';
}


template <class ST>
inline std::ostream& operator <<(quote_double_only_type1 o,
		const Set<ST>& in)
{
	return *o.ostr << '"' << in << '"';
}

#endif // !defined(DOXYGEN_IGNORE)


/// \enum escape_type0
/// The 'escape' manipulator.
///
/// Calls mysql_escape_string() in the MySQL C API on the following
/// argument to prevent any special SQL characters from being
/// interpreted.

enum escape_type0 { escape };


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

struct escape_type1
{
	std::ostream* ostr;
	escape_type1(std::ostream* o) :
	ostr(o)
	{
	}
};


inline escape_type1 operator <<(std::ostream& o,
		escape_type0 /*esc */)
{
	return escape_type1(&o);
}


struct escape_type2
{
	SQLQueryParms *qparms;
	escape_type2(SQLQueryParms* p) :
	qparms(p)
	{
	}
};


inline escape_type2 operator <<(SQLQueryParms& p,
		escape_type0 /*esc */)
{
	return escape_type2(&p);
}

#endif // !defined(DOXYGEN_IGNORE)


/// \brief Inserts a SQLString into a stream, escaping special SQL
/// characters
///
/// We actually only do the escaping if in.is_string is set but
/// in.dont_escape is not.  If that is not the case, we insert the
/// string data directly.

MYSQLPP_EXPORT SQLQueryParms& operator <<(escape_type2 p,
		SQLString& in);


/// \brief Inserts any type T into a stream that has an operator<<
/// defined for it.
///
/// Does not actually escape that data!  Use one of the other forms of
/// operator<< for the escape manipulator if you need escaping.  This
/// template exists to catch cases like inserting an \c int after the
/// escape manipulator: you don't actually want escaping in this
/// instance.

template <class T>
inline std::ostream& operator <<(escape_type1 o, const T& in)
{
	return *o.ostr << in;
}


template <>
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
		const std::string& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
		const char* const& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
		const ColData_Tmpl<std::string>& in);


template <>
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
		const ColData_Tmpl<const_string>& in);


/// \brief Inserts a C string into a stream, escaping special SQL
/// characters.
///
/// This version exists solely to handle constness problems.  We force
/// everything to the completely-const version: operator<<(escape_type1,
/// const char* const&).

template <>
inline std::ostream& operator <<(escape_type1 o,
		char* const& in)
{
	return operator <<(o, const_cast<const char* const&>(in));
}


/// \brief Inserts an array of char into a stream, escaping special SQL
/// characters.

inline std::ostream& operator <<(escape_type1 o,
		char in[])
{
	return operator <<(o, static_cast<const char* const&>(in));
}

inline std::ostream& operator <<(escape_type1 o,
		const char in[])
{
	return operator <<(o, const_cast<char* const&>(in));
}


/// \enum do_nothing_type0
/// \anchor do_nothing_manip
///
/// The 'do_nothing' manipulator.
///
/// Does exactly what it says: nothing. Used as a dummy manipulator when
/// you are required to use some manipulator but don't want anything to
/// be done to the following item. When used with SQLQueryParms it will
/// make sure that it does not get formatted in any way, overriding any
/// setting set by the template query.

enum do_nothing_type0
{
	do_nothing				///< insert into a std::ostream to override manipulation of next item
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

struct do_nothing_type1
{
	std::ostream* ostr;
	do_nothing_type1(std::ostream* o) :
	ostr(o)
	{
	}
};


inline do_nothing_type1 operator <<(std::ostream& o,
		do_nothing_type0 /*esc */)
{
	return do_nothing_type1(&o);
}


template <class T>
inline std::ostream& operator <<(do_nothing_type1 o, const T& in)
{
	return *o.ostr << in;
}


struct do_nothing_type2
{
	SQLQueryParms *qparms;
	do_nothing_type2(SQLQueryParms* p) :
	qparms(p)
	{
	}
};


inline do_nothing_type2 operator <<(SQLQueryParms& p,
		do_nothing_type0 /* esc */)
{
	return do_nothing_type2(&p);
}


MYSQLPP_EXPORT SQLQueryParms& operator <<(do_nothing_type2 p,
		SQLString& in);

#endif // !defined(DOXYGEN_IGNORE)


/// \enum ignore_type0
/// \anchor ignore_manip
///
/// The 'ignore' manipulator.
///
/// Only valid when used with SQLQueryParms. It's a dummy manipulator
/// like the <a href="#do_nothing_manip">do_nothing manipulator</a>,
/// except that it will not override formatting set by the template
/// query.  It is simply ignored.

enum ignore_type0
{
	ignore					///< insert into a std::ostream as a dummy manipulator
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

struct ignore_type2
{
	SQLQueryParms* qparms;
	ignore_type2(SQLQueryParms* p) :
	qparms(p)
	{
	}
};


inline ignore_type2 operator <<(SQLQueryParms& p,
		ignore_type0 /* esc*/)
{
	return ignore_type2(&p);
}


MYSQLPP_EXPORT SQLQueryParms& operator <<(ignore_type2 p,
		SQLString& in);

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace mysqlpp

#endif
Deleted lib/myset.cpp.
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



































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 myset.cpp - Implements the Set template.  (Not to be confused with
	std::set, which this template wraps.)

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "myset.h"

namespace mysqlpp {

template class Set<std::set<std::string> >;

} // end namespace mysqlpp

Deleted lib/myset.h.
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





























































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file myset.h
/// \brief Declares templates for generating custom containers used
/// elsewhere in the library.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_MYSET_H
#define MYSQLPP_MYSET_H

#include "common.h"

#include "coldata.h"
#include "stream2string.h"

#include <iostream>
#include <set>
#include <vector>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

template <class T, class key_type = typename T::key_type>
class MYSQLPP_EXPORT SetInsert
{
public:
	SetInsert(T* o) : object_(o) { }
	void operator ()(const key_type& data) { object_->insert(data); }

private:
	T* object_;
};

template <class T>
inline SetInsert< std::set<T> > set_insert(std::set<T>* o)
{
	return SetInsert< std::set<T> >(o);
}

template <class Insert>
void set2container(const char* str, Insert insert);

#endif // !defined(DOXYGEN_IGNORE)


/// \brief A special std::set derivative for holding MySQL data sets.

template <class Container = std::set<std::string> >
class MYSQLPP_EXPORT Set : public Container
{
public:
	/// \brief Default constructor
	Set() {};

	/// \brief Create object from a comma-separated list of values
	Set(const char* str)
	{
		set2container(str, set_insert(this));
	}
	
	/// \brief Create object from a comma-separated list of values
	Set(const std::string& str)
	{
		set2container(str.c_str(), set_insert(this));
	}
	
	/// \brief Create object from a comma-separated list of values
	Set(const ColData& str)
	{
		set2container(str.c_str(), set_insert(this));
	}

	/// \brief Insert this set's data into a C++ stream in
	/// comma-separated format.
	std::ostream& out_stream(std::ostream& s) const
	{
		typename Container::const_iterator i = Container::begin();
		typename Container::const_iterator e = Container::end();

		while (true) {
			s << *i;
			if (++i == e) {
				break;
			}
			s << ",";
		}
		
		return s;
	}

	/// \brief Convert this set's data to a string containing
	/// comma-separated items.
	operator std::string() { return stream2string<std::string>(*this); }
};


/// \brief Inserts a Set object into a C++ stream
template <class Container>
inline std::ostream& operator <<(std::ostream& s,
		const Set<Container>& d)
{
	return d.out_stream(s);
}


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

template <class Insert>
void set2container(const char* str, Insert insert)
{
	while (1) {
		MutableColData s("");
		while (*str != ',' && *str) {
			s += *str;
			str++;
		}

		insert(s);

		if (!*str) {
			break; 
		}

		str++;
	}
}

#endif // !defined(DOXYGEN_IGNORE)


} // end namespace mysqlpp

#endif
Deleted lib/mysql++.cpp.
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






































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 mysql++.cpp - Implements functions dealing with the library itself,
	as opposed to individual features of the library.

 Copyright (c) 2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "mysql++.h"

namespace mysqlpp {

unsigned int 
get_library_version()
{
	return MYSQLPP_HEADER_VERSION;
}

} // end namespace mysqlpp

Deleted lib/mysql++.h.in.
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












































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file mysql++.h
/// \brief The main MySQL++ header file.
///
/// This file brings in all MySQL++ headers except for custom.h and
/// custom-macros.h which are a strictly optional feature of MySQL++.
///
/// There is no point in trying to optimize which headers you include,
/// because the MySQL++ headers are so intertwined.  You can only get
/// trivial compile time benefits, at the expense of clarity.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_MYSQLPP_H
#define MYSQLPP_MYSQLPP_H

/// \brief Encode MySQL++ library version number.
///
/// This macro takes major, minor and bugfix numbers (e.g. 1, 2, and 3)
/// and encodes them like 0x010203.
#define MYSQLPP_VERSION(major, minor, bugfix) \
		(((major) << 16) | ((minor) << 8) | (bugfix))

/// \brief Get the library version number that mysql++.h comes from
///
/// MySQL++ Version number that the mysql++.h header file comes from,
/// encoded by MYSQLPP_VERSION macro.  Compare this value to what
/// mysqlpp_lib_version() returns in order to ensure that your program
/// is using header files from the same version of MySQL++ as the
/// actual library you're linking to.
#define MYSQLPP_HEADER_VERSION MYSQLPP_VERSION(@MYSQLPP_VERSION_MAJOR@, @MYSQLPP_VERSION_MINOR@, @MYSQLPP_VERSION_BUGFIX@)

// This #include order gives the fewest redundancies in the #include
// dependency chain.
#include "connection.h"
#include "query.h"
#include "sql_types.h"

namespace mysqlpp {

/// \brief Get the current MySQL++ library version number
///
/// MySQL++ version number that the program is actually linked to,
/// encoded by MYSQLPP_VERSION macro.  Compare this value to the
/// MYSQLPP_HEADER_VERSION constant in order to ensure that your
/// program is using header files from the same version of MySQL++ as
/// the actual library you're linking to.
MYSQLPP_EXPORT unsigned int get_library_version();

} // end namespace mysqlpp

#endif // !defined(MYSQLPP_MYSQLPP_H)


/**
	\mainpage MySQL++ Reference Manual

	\section getting_started Getting Started

	The best place to get started is the
	<a href="../userman/index.html">user manual</a>. It provides
	a guide to the example programs and more.


	\section classes Major Classes

	In MySQL++, the main user-facing classes are mysqlpp::Connection,
	mysqlpp::Query, mysqlpp::Result, and mysqlpp::Row.

	In addition, MySQL++ has a mechanism called Specialized SQL
	Structures (SSQLS), which allow you to create C++ structures
	that parallel the definition of the tables in your database
	schema. These let you manipulate the data in your database using
	native C++ data structures. Programs using this feature often
	include very little SQL code, because MySQL++ can generate most
	of what you need automatically when using SSQLSes. There is a
	whole chapter in the user manual on how to use this feature of
	the library, plus a section in the user manual's tutorial chapter
	to introduce it. It's possible to use MySQL++ effectively without
	using SSQLS, but it sure makes some things a lot easier.


	\section files Major Files

	The only two header files your program ever needs to include
	are mysql++.h, and optionally custom.h. (The latter implements
	the SSQLS mechanism.) All of the other files are used within
	the library only.


	\section user_questions If You Have Questions...

	If you want to email someone to ask questions about this library,
	we greatly prefer that you send mail to the MySQL++ mailing list,
	which you can subscribe to here: http://lists.mysql.com/plusplus

	That mailing list is archived, so if you have questions, do a
	search to see if the question has been asked before.

	You may find people's individual email addresses in various
	files within the MySQL++ distribution. Please do not send mail
	to them unless you are sending something that is inherently
	personal. Questions that are about MySQL++ usage may well be
	ignored if you send them to our personal email accounts. Those of
	us still active in MySQL++ development monitor the mailing list,
	so you aren't getting any extra "coverage" by sending messages
	to those addresses in addition to the mailing list.


	\section licensing Licensing

	MySQL++ is licensed under the GNU Lesser General Public License,
	which you should have received with the distribution package in
	a file called "LGPL" or "LICENSE". You can also view it here:
	http://www.gnu.org/licenses/lgpl.html or receive a copy by
	writing to Free Software Foundation, Inc., 51 Franklin Street,
	Fifth Floor, Boston, MA 02110-1301, USA.
*/

Deleted lib/noexceptions.h.
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










































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file noexceptions.h
/// \brief Declares interface that allows exceptions to be optional
///
/// A class may inherit from OptionalExceptions, which will add to it
/// a mechanism by which a user can tell objects of that class to
/// suppress exceptions.  (They are enabled by default.)  This module
/// also declares a NoExceptions class, objects of which take a
/// reference to any class derived from OptionalExceptions.  The
/// NoExceptions constructor calls the method that disables exceptions,
/// and the destructor reverts them to the previous state.  One uses
/// the NoExceptions object within a scope to suppress exceptions in
/// that block, without having to worry about reverting the setting when
/// the block exits.

/***********************************************************************
 Copyright (c) 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_NOEXCEPTIONS_H
#define MYSQLPP_NOEXCEPTIONS_H

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT NoExceptions;
#endif

/// \brief Interface allowing a class to have optional exceptions.
///
/// A class derives from this one to acquire a standard interface for
/// disabling exceptions, possibly only temporarily.  By default,
/// exceptions are enabled.

class MYSQLPP_EXPORT OptionalExceptions
{
public:
	/// \brief Default constructor
	///
	/// \param e if true, exceptions are enabled (this is the default)
	OptionalExceptions(bool e = true) :
	exceptions_(e)
	{
	}

	/// \brief Destroy object
	virtual ~OptionalExceptions() { }

	/// \brief Enable exceptions from the object
	void enable_exceptions() { exceptions_ = true; }

	/// \brief Disable exceptions from the object
	void disable_exceptions() { exceptions_ = false; }

	/// \brief Returns true if exceptions are enabled
	bool throw_exceptions() const { return exceptions_; }

protected:
	/// \brief Sets the exception state to a particular value
	///
	/// This method is protected because it is only intended for use by
	/// subclasses' copy constructors and the like.
	void set_exceptions(bool e) { exceptions_ = e; }

	/// \brief Declare NoExceptions to be our friend so it can access
	/// our protected functions.
	friend class NoExceptions;

private:
	bool exceptions_;
};


/// \brief Disable exceptions in an object derived from
/// OptionalExceptions.
///
/// This class was designed to be created on the stack, taking a
/// reference to a subclass of OptionalExceptions. (We call that our
/// "associate" object.) On creation, we save that object's current
/// exception state, and disable exceptions. On destruction, we restore
/// our associate's previous state.

class MYSQLPP_EXPORT NoExceptions
{
public:
	/// \brief Constructor
	///
	/// Takes a reference to an OptionalExceptions derivative,
	/// saves that object's current exception state, and disables
	/// exceptions.
	NoExceptions(OptionalExceptions& a) :
	assoc_(a),
	exceptions_were_enabled_(a.throw_exceptions())
	{
		assoc_.disable_exceptions();
	}

	/// \brief Destructor
	///
	/// Restores our associate object's previous exception state.
	~NoExceptions()
	{
		assoc_.set_exceptions(exceptions_were_enabled_);
	}
	
private:
	OptionalExceptions& assoc_;
	bool exceptions_were_enabled_;

	// Hidden assignment operator and copy ctor, because we should not
	// be copied.
	NoExceptions(const NoExceptions&);
	NoExceptions& operator=(const NoExceptions&);
};

} // end namespace mysqlpp

#endif // MYSQLPP_NOEXCEPTIONS_H

Deleted lib/null.h.
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






















































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file null.h
/// \brief Declares classes that implement SQL "null" semantics within
/// C++'s type system.
///
/// This is required because C++'s own NULL type is not semantically
/// the same as SQL nulls.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_NULL_H
#define MYSQLPP_NULL_H

#include "exceptions.h"

#include <iostream>

namespace mysqlpp {


/// \brief The type of the global mysqlpp::null object.
///
/// This class is for internal use only.  Normal code should use
/// Null instead.
class MYSQLPP_EXPORT null_type
{
public:
#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.
	template <class Type> operator Type()
	{
		throw BadNullConversion();
		return Type();
	}
#endif // !defined(DOXYGEN_IGNORE)
};

/// \brief Global 'null' instance.  Use wherever you need a SQL null.
/// (As opposed to a C++ language null pointer or null character.)
const null_type null = null_type();


/// \brief Class for objects that define SQL null in terms of
/// MySQL++'s null_type.
///
/// Returns a null_type instance when you ask what null is, and is
/// "(NULL)" when you insert it into a C++ stream.
///
/// Used for the behavior parameter for template Null
struct NullisNull
{
#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.
	static null_type null_is() { return null_type(); }

	static std::ostream& null_ostr(std::ostream& o)
	{
		o << "(NULL)";
		return o;
	}
#endif // !defined(DOXYGEN_IGNORE)
};


/// \brief Class for objects that define SQL null as 0.
///
/// Returns 0 when you ask what null is, and is zero when you insert it
/// into a C++ stream.
///
/// Used for the behavior parameter for template Null
struct NullisZero
{
#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.
	static int null_is() { return 0; }
	
	static std::ostream& null_ostr(std::ostream& o)
	{
		o << 0;
		return o;
	}
#endif // !defined(DOXYGEN_IGNORE)
};

/// \brief Class for objects that define SQL null as a blank C string.
///
/// Returns "" when you ask what null is, and is empty when you insert
/// it into a C++ stream.
///
/// Used for the behavior parameter for template Null
struct NullisBlank
{
#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.
	static const char *null_is() { return ""; }
	
	static std::ostream& null_ostr(std::ostream& o)
	{
		o << "";
		return o;
	}
#endif // !defined(DOXYGEN_IGNORE)
};


/// \brief Class for holding data from a SQL column with the NULL
/// attribute.
///
/// This template is necessary because there is nothing in the C++ type
/// system with the same semantics as SQL's null.  In SQL, a column can
/// have the optional 'NULL' attribute, so there is a difference in 
/// type between, say an \c int column that can be null and one that
/// cannot be.  C++'s NULL constant does not have these features.
///
/// It's important to realize that this class doesn't hold nulls,
/// it holds data that \e can \e be null.  It can hold a non-null
/// value, you can then assign null to it (using MySQL++'s global
/// \c null object), and then assign a regular value to it again; the
/// object will behave as you expect throughout this process.
///
/// Because one of the template parameters is a C++ type, the typeid()
/// for a null \c int is different than for a null \c string, to pick
/// two random examples.  See type_info.cpp for the table SQL types that
/// can be null.
template <class Type, class Behavior = NullisNull> class Null
{
public:
	/// \brief The object's value, when it is not SQL null
	Type data;
	
	/// \brief If set, this object is considered equal to SQL null.
	///
	/// This flag affects how the Type() and << operators work.
	bool is_null;

	/// \brief Type of the data stored in this object, when it is not
	/// equal to SQL null.
	typedef Type value_type;

	/// \brief Default constructor
	///
	/// "data" member is left uninitialized by this ctor, because we
	/// don't know what to initialize it to.
	Null() :
	is_null(false)
	{
	}

	/// \brief Initialize the object with a particular value.
	///
	/// The object is marked as "not null" if you use this ctor.  This
	/// behavior exists because the class doesn't encode nulls, but
	/// rather data which \e can \e be null.  The distinction is
	/// necessary because 'NULL' is an optional attribute of SQL
	/// columns.
	Null(const Type& x) :
	data(x),
	is_null(false)
	{
	}

	/// \brief Construct a Null equal to SQL null
	///
	/// This is typically used with the global \c null object. (Not to
	/// be confused with C's NULL type.)  You can say something like...
	/// \code
	/// Null<int> foo = null;
	/// \endcode
	/// ...to get a null \c int.
	Null(const null_type& n) :
	is_null(true)
	{
	}

	/// \brief Converts this object to Type
	///
	/// If is_null is set, returns whatever we consider that null "is",
	/// according to the Behavior parameter you used when instantiating
	/// this template.  See NullisNull, NullisZero and NullisBlank.
	///
	/// Otherwise, just returns the 'data' member.
	operator Type&()
	{
		if (is_null)
			return data = Behavior::null_is();
		else
			return data;
	}

	/// \brief Assign a value to the object.
	///
	/// This marks the object as "not null" as a side effect.
	Null& operator =(const Type& x)
	{
		data = x;
		is_null = false;
		return *this;
	}

	/// \brief Assign SQL null to this object.
	///
	/// This just sets the is_null flag; the data member is not
	/// affected until you call the Type() operator on it.
	Null& operator =(const null_type& n)
	{
		is_null = true;
		return *this;
	}
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

// Specialization the Null template for \c void
template <> class Null<void>
{
public:
	bool is_null;
	typedef void value_type;

	Null() :
	is_null(false)
	{
	}
	
	Null(const null_type&) :
	is_null(true)
	{
	}

	Null& operator =(const null_type&)
	{
		is_null = true;
		return *this;
	}
};

#endif // !defined(DOXYGEN_IGNORE)


/// \brief Inserts null-able data into a C++ stream if it is not
/// actually null.  Otherwise, insert something appropriate for null
/// data.
template <class Type, class Behavior>
inline std::ostream& operator <<(std::ostream& o,
		const Null<Type, Behavior>& n)
{
	if (n.is_null)
		return Behavior::null_ostr(o);
	else
		return o << n.data;
}

} // end namespace mysqlpp

#endif
Deleted lib/qparms.cpp.
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





































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 qparms.cpp - Implements the SQLQuery class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "qparms.h"

#include "query.h"

using namespace std;

namespace mysqlpp {

SQLString&
SQLQueryParms::operator [](const char* str)
{
	if (parent_) {
		return operator [](parent_->parsed_nums_[str]);
	}
	throw ObjectNotInitialized("SQLQueryParms object has no parent!");
}

const SQLString&
SQLQueryParms::operator[] (const char* str) const
{
	if (parent_) {
		return operator [](parent_->parsed_nums_[str]);
	}
	throw ObjectNotInitialized("SQLQueryParms object has no parent!");
}

SQLQueryParms
SQLQueryParms::operator +(const SQLQueryParms& other) const
{
	if (other.size() <= size()) {
		return *this;
	}
	SQLQueryParms New = *this;
	size_t i;
	for (i = size(); i < other.size(); i++) {
		New.push_back(other[i]);
	}

	return New;
}


} // end namespace mysqlpp
Deleted lib/qparms.h.
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































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file qparms.h
/// \brief Declares the template query parameter-related stuff.
///
/// The classes defined in this file are used by class Query when it
/// parses a template query: they hold information that it finds in the
/// template, so it can assemble a SQL statement later on demand.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_QPARMS_H
#define MYSQLPP_QPARMS_H

#include "sql_string.h"

#include <vector>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT Query;
#endif

/// \brief This class holds the parameter values for filling
/// template queries. 
class MYSQLPP_EXPORT SQLQueryParms : public std::vector<SQLString>
{
public:
	/// \brief Abbreviation so some of the declarations below don't
	/// span many lines.
	typedef const SQLString& ss;

	/// \brief Default constructor
	SQLQueryParms() :
	parent_(0),
	processing_(false)
	{
	}
	
	/// \brief Create object
	///
	/// \param p pointer to the query object these parameters are tied
	/// to
	SQLQueryParms(Query* p) :
	parent_(p),
	processing_(false)
	{
	}
	
	/// \brief Returns true if we are bound to a query object.
	///
	/// Basically, this tells you which of the two ctors were called.
	bool bound()
	{
		return parent_ != 0;
	}

	/// \brief Clears the list
	void clear()
	{
		erase(begin(), end());
	}

	/// \brief Access element number n
	SQLString& operator [](size_type n)
	{
		if (n >= size())
			insert(end(), (n + 1) - size(), "");
		return std::vector<SQLString>::operator [](n);
	}

	/// \brief Access element number n
	const SQLString& operator [](size_type n) const
	{
		return std::vector<SQLString>::operator [](n);
	}
	
	/// \brief Access the value of the element with a key of str.
	SQLString& operator [](const char *str);

	/// \brief Access the value of the element with a key of str.
	const SQLString& operator [](const char *str) const;

	/// \brief Adds an element to the list
	SQLQueryParms& operator <<(const SQLString& str)
	{
		push_back(str);
		return *this;
	}

	/// \brief Adds an element to the list
	SQLQueryParms& operator +=(const SQLString& str)
	{
		push_back(str);
		return *this;
	}

	/// \brief Build a composite of two parameter lists
	///
	/// If this list is (a, b) and \c other is (c, d, e, f, g), then
	/// the returned list will be (a, b, e, f, g).  That is, all of this
	/// list's parameters are in the returned list, plus any from the
	/// other list that are in positions beyond what exist in this list.
	///
	/// If the two lists are the same length or this list is longer than
	/// the \c other list, a copy of this list is returned.
	SQLQueryParms operator +(
			const SQLQueryParms& other) const;

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.
	void set(ss a)
	{
		clear();
		*this << a;
	}
	void set(ss a, ss b)
	{
		clear();
		*this << a << b;
	}
	void set(ss a, ss b, ss c)
	{
		clear();
		*this << a << b << c;
	}
	void set(ss a, ss b, ss c, ss d)
	{
		clear();
		*this << a << b << c << d;
	}
	void set(ss a, ss b, ss c, ss d, ss e)
	{
		clear();
		*this << a << b << c << d << e;
	}
	void set(ss a, ss b, ss c, ss d, ss e, ss f)
	{
		clear();
		*this << a << b << c << d << e << f;
	}
	void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g)
	{
		clear();
		*this << a << b << c << d << e << f << g;
	}
	void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)
	{
		clear();
		*this << a << b << c << d << e << f << g << h;
	}
	void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)
	{
		clear();
		*this << a << b << c << d << e << f << g << h << i;
	}
	void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i, ss j)
	{
		clear();
		*this << a << b << c << d << e << f << g << h << i << j;
	}
	void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i, ss j, ss k)
	{
		clear();
		*this << a << b << c << d << e << f << g << h << i << j << k;
	}
#endif // !defined(DOXYGEN_IGNORE)

	/// \brief Set the template query parameters.
	///
	/// Sets parameter 0 to a, parameter 1 to b, etc. There are
	/// overloaded versions of this function that take anywhere from
	/// one to a dozen parameters.
	void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g,
			ss h, ss i, ss j, ss k, ss l)
	{
		clear();
		*this << a << b << c << d << e << f << g << h << i << j << k << l;
	}

private:
	friend class Query;

	Query* parent_;
	bool processing_;	///< true if we're building a query string
};


/// \brief Used within Query to hold elements for parameterized
/// queries.
///
/// Each element has three parts:
///
/// The concept behind the \c before variable needs a little explaining.
/// When a template query is parsed, each parameter is parsed into one
/// of these SQLParseElement objects, but the non-parameter parts of the
/// template also have to be stored somewhere.  MySQL++ chooses to
/// attach the text leading up to a parameter to that parameter.  So,
/// the \c before string is simply the text copied literally into the
/// finished query before we insert a value for the parameter.
///
/// The \c option character is currently one of 'q', 'Q', 'r', 'R' or
/// ' '.  See the "Template Queries" chapter in the user manual for
/// details.
///
/// The position value (\c num) allows a template query to have its
/// parameters in a different order than in the Query method call.
/// An example of how this can be helpful is in the "Template Queries"
/// chapter of the user manual.

struct SQLParseElement
{
	/// \brief Create object
	///
	/// \param b the 'before' value
	/// \param o the 'option' value
	/// \param n the 'num' value
	SQLParseElement(std::string b, char o, signed char n) :
	before(b),
	option(o),
	num(n)
	{
	}
	
	std::string before;		///< string inserted before the parameter
	char option;			///< the parameter option, or blank if none
	signed char num;		///< the parameter position to use
};

} // end namespace mysqlpp

#endif // !defined(MYSQLPP_QPARMS_H)

Deleted lib/query.cpp.
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
















































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 query.cpp - Implements the Query class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "query.h"

#include "autoflag.h"
#include "connection.h"

namespace mysqlpp {

Query::Query(Connection* c, bool te) :
#if defined(_MSC_VER) && !defined(_STLP_VERSION) && !defined(_STLP_VERSION_STR)
// prevents a double-init memory leak in native VC++ RTL (not STLport!)
std::ostream(std::_Noinit), 
#else
std::ostream(0),
#endif
OptionalExceptions(te),
Lockable(false),
def(this),
conn_(c),
success_(false)
{
	init(&sbuffer_);
	success_ = true;
}

Query::Query(const Query& q) :
#if defined(_MSC_VER) && !defined(_STLP_VERSION) && !defined(_STLP_VERSION_STR)
// ditto above
std::ostream(std::_Noinit),
#else
std::ostream(0),
#endif
OptionalExceptions(q.throw_exceptions()),
Lockable(q.locked()),
def(q.def),
conn_(q.conn_),
success_(q.success_)
{
	init(&sbuffer_);
}


Query&
Query::operator=(const Query& rhs)
{
	set_exceptions(rhs.throw_exceptions());
	set_lock(rhs.locked());
	def = rhs.def;
	conn_ = rhs.conn_;
	success_ = rhs.success_;

	return *this;
}


my_ulonglong
Query::affected_rows() const
{
	return conn_->affected_rows();
}


std::string
Query::error()
{
	return conn_->error();
}


bool
Query::exec(const std::string& str)
{
	success_ = !mysql_real_query(&conn_->mysql_, str.data(),
			static_cast<unsigned long>(str.length()));
	if (!success_ && throw_exceptions()) {
		throw BadQuery(error());
	}
	else {
		return success_;
	}
}


ResNSel
Query::execute(const SQLString& str)
{
	if ((parse_elems_.size() == 2) && !def.processing_) {
		// We're a template query and we haven't gone through this path
		// before, so take str to be a lone parameter for the query.
		// We will come back through this function with a completed
		// query, but the processing_ flag will be reset, allowing us to
		// take the 'else' path, avoiding an infinite loop.
		AutoFlag<> af(def.processing_);
		return execute(SQLQueryParms() << str);
	}
	else {
		// Take str to be the entire query string
		return execute(str.data(), str.length());
	}
}


ResNSel
Query::execute(const char* str)
{
	return execute(SQLString(str));
}


ResNSel
Query::execute(const char* str, size_t len)
{
	if (lock()) {
		success_ = false;
		if (throw_exceptions()) {
			throw LockFailed();
		}
		else {
			return ResNSel();
		}
	}

	success_ = !mysql_real_query(&conn_->mysql_, str, len);

	unlock();
	if (success_) {
		return ResNSel(conn_);
	}
	else if (throw_exceptions()) {
		throw BadQuery(error());
	}
	else {
		return ResNSel();
	}
}


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

ResNSel
Query::execute(SQLQueryParms& p)
{
	return execute(str(p, parse_elems_.size() ? DONT_RESET : RESET_QUERY));
}

#endif // !defined(DOXYGEN_IGNORE)


std::string
Query::info()
{
	return conn_->info();
}


my_ulonglong
Query::insert_id()
{
	return conn_->insert_id();
}


bool
Query::lock()
{
    return conn_->lock();
}


bool 
Query::more_results()
{
#if MYSQL_VERSION_ID > 41000		// only in MySQL v4.1 +
	return mysql_more_results(&conn_->mysql_);
#else
	return false;
#endif
}


void
Query::parse()
{
	std::string str = "";
	char num[4];
	std::string name;
	char *s, *s0;
	s0 = s = preview_char();
	while (*s) {
		if (*s == '%') {
			// Following might be a template parameter declaration...
			s++;
			if (*s == '%') {
				// Doubled percent sign, so insert literal percent sign.
				str += *s++;
			}
			else if (isdigit(*s)) {
				// Number following percent sign, so it signifies a
				// positional parameter.  First step: find position
				// value, up to 3 digits long.
				num[0] = *s;
				s++;
				if (isdigit(*s)) {
					num[1] = *s;
					num[2] = 0;
					s++;
					if (isdigit(*s)) {
						num[2] = *s;
						num[3] = 0;
						s++;
					}
					else {
						num[2] = 0;
					}
				}
				else {
					num[1] = 0;
				}
				signed char n = atoi(num);

				// Look for option character following position value.
				char option = ' ';
				if (*s == 'q' || *s == 'Q' || *s == 'r' || *s == 'R') {
					option = *s++;
				}

				// Is it a named parameter?
				if (*s == ':') {
					// Save all alphanumeric and underscore characters
					// following colon as parameter name.
					s++;
					for (/* */; isalnum(*s) || *s == '_'; ++s) {
						name += *s;
					}

					// Eat trailing colon, if it's present.
					if (*s == ':') {
						s++;
					}

					// Update maps that translate parameter name to
					// number and vice versa.
					if (n >= static_cast<short>(parsed_names_.size())) {
						parsed_names_.insert(parsed_names_.end(),
								static_cast<std::vector<std::string>::size_type>(
										n + 1) - parsed_names_.size(),
								std::string());
					}
					parsed_names_[n] = name;
					parsed_nums_[name] = n;
				}

				// Finished parsing parameter; save it.
				parse_elems_.push_back(SQLParseElement(str, option, n));
				str = "";
				name = "";
			}
			else {
				// Insert literal percent sign, because sign didn't
				// precede a valid parameter string; this allows users
				// to play a little fast and loose with the rules,
				// avoiding a double percent sign here.
				str += '%';
			}
		}
		else {
			// Regular character, so just copy it.
			str += *s++;
		}
	}

	parse_elems_.push_back(SQLParseElement(str, ' ', -1));
	delete[] s0;
}


SQLString*
Query::pprepare(char option, SQLString& S, bool replace)
{
	if (S.processed) {
		return &S;
	}

	if (option == 'r' || (option == 'q' && S.is_string)) {
		char *s = new char[S.size() * 2 + 1];
		mysql_real_escape_string(&conn_->mysql_, s, S.data(),
				static_cast<unsigned long>(S.size()));
		SQLString *ss = new SQLString("'");
		*ss += s;
		*ss += "'";
		delete[] s;

		if (replace) {
			S = *ss;
			S.processed = true;
			delete ss;
			return &S;
		}
		else {
			return ss;
		}
	}
	else if (option == 'R' || (option == 'Q' && S.is_string)) {
		SQLString *ss = new SQLString("'" + S + "'");

		if (replace) {
			S = *ss;
			S.processed = true;
			delete ss;
			return &S;
		}
		else {
			return ss;
		}
	}
	else {
		if (replace) {
			S.processed = true;
		}
		return &S;
	}
}


char*
Query::preview_char()
{
	const std::string& str(sbuffer_.str());
	char* s = new char[str.size() + 1];
	memcpy(s, str.data(), str.size()); 
	s[str.size()] = '\0';
	return s;
}


void
Query::proc(SQLQueryParms& p)
{
	sbuffer_.str("");

	for (std::vector<SQLParseElement>::iterator i = parse_elems_.begin();
			i != parse_elems_.end(); ++i) {
		MYSQLPP_QUERY_THISPTR << i->before;
		int num = i->num;
		if (num >= 0) {
			SQLQueryParms* c;
			if (size_t(num) < p.size()) {
				c = &p;
			}
			else if (size_t(num) < def.size()) {
				c = &def;
			}
			else {
				*this << " ERROR";
				throw BadParamCount(
						"Not enough parameters to fill the template.");
			}

			SQLString& param = (*c)[num];
			SQLString* ss = pprepare(i->option, param, c->bound());
			MYSQLPP_QUERY_THISPTR << *ss;
			if (ss != &param) {
				// pprepare() returned a new string object instead of
				// updating param in place, so we need to delete it.
				delete ss;
			}
		}
	}
}

void
Query::reset()
{
	seekp(0);
	clear();
	sbuffer_.str("");

	parse_elems_.clear();
	def.clear();
}


Result 
Query::store(const SQLString& str)
{
	if ((parse_elems_.size() == 2) && !def.processing_) {
		// We're a template query and we haven't gone through this path
		// before, so take str to be a lone parameter for the query.
		// We will come back through this function with a completed
		// query, but the processing_ flag will be reset, allowing us to
		// take the 'else' path, avoiding an infinite loop.
		AutoFlag<> af(def.processing_);
		return store(SQLQueryParms() << str);
	}
	else {
		// Take str to be the entire query string
		return store(str.data(), str.length());
	}
}


Result
Query::store(const char* str)
{
	return store(SQLString(str));
}


Result
Query::store(const char* str, size_t len)
{
	if (lock()) {
		success_ = false;
		if (throw_exceptions()) {
			throw LockFailed();
		}
		else {
			return Result();
		}
	}


	if (success_ = !mysql_real_query(&conn_->mysql_, str, len)) {
		MYSQL_RES* res = mysql_store_result(&conn_->mysql_);
		if (res) {
			unlock();
			return Result(res, throw_exceptions());
		}
		else {
			success_ = false;
		}
	}
	unlock();

	// One of the MySQL API calls failed, but it's not an error if we
	// just get an empty result set.  It happens when store()ing a query
	// that doesn't always return results.  While it's better to use 
	// exec*() in that situation, it's legal to call store() instead,
	// and sometimes you have no choice.  For example, if the SQL comes
	// from outside the program so you can't predict whether there will
	// be results.
	if (conn_->errnum() && throw_exceptions()) {
		throw BadQuery(error());
	}
	else {
		return Result();
	}
}


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

Result
Query::store(SQLQueryParms& p)
{
	return store(str(p, parse_elems_.size() ? DONT_RESET : RESET_QUERY));
}

#endif // !defined(DOXYGEN_IGNORE)


Result
Query::store_next()
{
#if MYSQL_VERSION_ID > 41000		// only in MySQL v4.1 +
	if (lock()) {
		if (throw_exceptions()) {
			throw LockFailed();
		}
		else {
			return Result();
		}
	}

	int ret;
	if ((ret = mysql_next_result(&conn_->mysql_)) == 0) {
		// There are more results, so return next result set.
		MYSQL_RES* res = mysql_store_result(&conn_->mysql_);
		unlock();
		if (res) {
			return Result(res, throw_exceptions());
		} 
		else {
			// Result set is null, but throw an exception only i it is
			// null because of some error.  If not, it's just an empty
			// result set, which is harmless.  We return an empty result
			// set if exceptions are disabled, as well.
			if (conn_->errnum() && throw_exceptions()) {
				throw BadQuery(error());
			} 
			else {
				return Result();
			}
		}
	}
	else {
		// No more results, or some other error occurred.
		unlock();
		if (throw_exceptions()) {
			if (ret > 0) {
				throw BadQuery(error());
			}
			else {
				throw EndOfResultSets();
			}
		}
		else {
			return Result();
		}
	}
#else
	return store();
#endif // MySQL v4.1+
}


std::string
Query::str(SQLQueryParms& p)
{
	if (!parse_elems_.empty()) {
		proc(p);
	}

	return sbuffer_.str();
}


std::string
Query::str(SQLQueryParms& p, query_reset r)
{
	std::string tmp = str(p);
	if (r == RESET_QUERY) {
		reset();
	}
	return tmp;
}


bool
Query::success()
{
	return success_ && conn_->success();
}


void
Query::unlock()
{
	conn_->unlock();
}


ResUse
Query::use(const SQLString& str)
{
	if ((parse_elems_.size() == 2) && !def.processing_) {
		// We're a template query and we haven't gone through this path
		// before, so take str to be a lone parameter for the query.
		// We will come back through this function with a completed
		// query, but the processing_ flag will be reset, allowing us to
		// take the 'else' path, avoiding an infinite loop.
		AutoFlag<> af(def.processing_);
		return use(SQLQueryParms() << str);
	}
	else {
		// Take str to be the entire query string
		return use(str.data(), str.length());
	}
}


ResUse
Query::use(const char* str)
{
	return use(SQLString(str));
}


ResUse
Query::use(const char* str, size_t len)
{
	if (lock()) {
		success_ = false;
		if (throw_exceptions()) {
			throw LockFailed();
		}
		else {
			return ResUse();
		}
	}

	if (success_ = !mysql_real_query(&conn_->mysql_, str, len)) {
		MYSQL_RES* res = mysql_use_result(&conn_->mysql_);
		if (res) {
			unlock();
			return ResUse(res, conn_, throw_exceptions());
		}
	}
	unlock();

	// One of the MySQL API calls failed, but it's not an error if we
	// just get an empty result set.  It happens when use()ing a query
	// that doesn't always return results.  While it's better to use 
	// exec*() in that situation, it's legal to call use() instead, and
	// sometimes you have no choice.  For example, if the SQL comes
	// from outside the program so you can't predict whether there will
	// be results.
	if (conn_->errnum() && throw_exceptions()) {
		throw BadQuery(error());
	}
	else {
		return ResUse();
	}
}


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

ResUse
Query::use(SQLQueryParms& p)
{
	return use(str(p, parse_elems_.size() ? DONT_RESET : RESET_QUERY));
}

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace mysqlpp

Deleted lib/query.h.
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


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file query.h
/// \brief Defines a class for building and executing SQL queries.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_QUERY_H
#define MYSQLPP_QUERY_H

#include "common.h"

#include "lockable.h"
#include "noexceptions.h"
#include "qparms.h"
#include "querydef.h"
#include "result.h"
#include "row.h"
#include "sql_string.h"

#include <deque>
#include <iomanip>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <vector>

#ifdef HAVE_EXT_SLIST
#  include <ext/slist>
#else
#  if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
#      include <slist>
#  endif
#endif

/// \def MYSQLPP_QUERY_THISPTR
/// \brief Helper macro used inside MySQL++ to work around a VC++ 2003 bug
///
/// This macro returns '*this', either directly or upcast to Query's
/// base class to work around an error in the overloaded operator
/// lookup logic in VC++ 2003.  For an explanation of the problem, see:
/// http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
#if defined(_MSC_VER) && (_MSC_VER < 1400)
#	define MYSQLPP_QUERY_THISPTR dynamic_cast<std::ostream&>(*this)
#else
#	define MYSQLPP_QUERY_THISPTR *this
#endif

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT Connection;
#endif

/// \brief Used for indicating whether a query object should auto-reset
enum query_reset { DONT_RESET, RESET_QUERY };

/// \brief A class for building and executing SQL queries.
///
/// This class is derived from SQLQuery. It adds to that a tie between
/// the query object and a MySQL++
/// \link mysqlpp::Connection Connection \endlink object, so that
/// the query can be sent to the MySQL server we're connected to.
///
/// One does not generally create Query objects directly. Instead, call
/// mysqlpp::Connection::query() to get one tied to that connection.
///
/// There are several ways to build and execute SQL queries with this
/// class.
///
/// The way most like other database libraries is to pass a SQL
/// statement to one of the
/// \link mysqlpp::Query::execute() exec*(), \endlink
/// \link mysqlpp::Query::store() store*(), \endlink or use() methods
/// taking a C or C++ string.  The query is executed immediately, and
/// any results returned.
///
/// For more complicated queries, you can use Query's stream interface.
/// You simply build up a query using the Query instance as you would
/// any other C++ stream object. When the query string is complete, you
/// call the overloaded version of \c exec*(), \c store*() or \c use()
/// that takes no parameters, which executes the built query and returns
/// any results.
///
/// If you are using the library's Specialized SQL Structures feature,
/// Query has several special functions for generating common SQL
/// queries from those structures. For instance, it offers the
/// \link mysqlpp::Query::insert() insert() \endlink method, which
/// builds an INSERT query to add the contents of the SSQLS to the
/// database. As with the stream interface, these methods only build
/// the query string; call one of the parameterless methods mentioned
/// previously to actually execute the query.
///
/// Finally, you can build "template queries". This is something like
/// C's \c printf() function, in that you insert a specially-formatted
/// query string into the object which contains placeholders for data.
/// You call the parse() method to tell the Query object that the query
/// string contains placeholders. Once that's done, you can call any of
/// the many overloaded methods that take a number of SQLStrings (up to
/// 25 by default) or any type that can be converted to SQLString, and
/// those parameters will be inserted into the placeholders. When you
/// call one of the parameterless functions the execute the query, the
/// final query string is assembled and sent to the server.
///
/// See the user manual for more details about these options.

class MYSQLPP_EXPORT Query : public std::ostream,
		public OptionalExceptions, public Lockable
{
public:
	/// \brief Create a new query object attached to a connection.
	///
	/// This is the constructor used by mysqlpp::Connection::query().
	///
	/// \param c connection the finished query should be sent out on
	/// \param te if true, throw exceptions on errors
	Query(Connection* c, bool te = true);

	/// \brief Create a new query object as a copy of another.
	///
	/// This is \b not a traditional copy ctor!  Its only purpose is to
	/// make it possible to assign the return of Connection::query()
	/// to an empty Query object.  In particular, the stream buffer and
	/// template query stuff will be empty in the copy, regardless of
	/// what values they have in the original.
	Query(const Query& q);

	/// \brief Assign another query's state to this object
	///
	/// The same caveats apply to this operator as apply to the copy
	/// ctor.
	Query& operator=(const Query& rhs);

	/// \brief Get the last error message that was set.
	///
	/// This class has an internal error message string, but if it
	/// isn't set, we return the last error message that happened
	/// on the connection we're bound to instead.
	std::string error();

	/// \brief Returns true if the last operation succeeded
	///
	/// Returns true if the last query succeeded, and the associated
	/// Connection object's success() method also returns true.  If
	/// either object is unhappy, this method returns false.
	bool success();

	/// \brief Treat the contents of the query string as a template
	/// query.
	///
	/// This method sets up the internal structures used by all of the
	/// other members that accept template query parameters.  See the
	/// "Template Queries" chapter in the user manual for more
	/// information.
	void parse();

	/// \brief Reset the query object so that it can be reused.
	///
	/// This erases the query string and the contents of the parameterized
	/// query element list.
	void reset();

	/// \brief Return the query string currently in the buffer.
	std::string preview() { return str(def); }

	/// \brief Return the query string currently in the buffer with
	/// template query parameter substitution.
	///
	/// \param arg0 the value to substitute for the first template query
	/// parameter
	std::string preview(const SQLString& arg0)
			{ return preview(SQLQueryParms() << arg0); }

	/// \brief Return the query string currently in the buffer.
	std::string preview(SQLQueryParms& p) { return str(p); }

	/// \brief Get built query as a null-terminated C++ string
	std::string str() { return str(def); }

	/// \brief Get built query as a null-terminated C++ string with
	/// template query parameter substitution.
	///
	/// \param arg0 the value to substitute for the first template query
	/// parameter
	std::string str(const SQLString& arg0)
			{ return preview(SQLQueryParms() << arg0); }

	/// \brief Get built query as a null-terminated C++ string
	///
	/// \param r if equal to \c RESET_QUERY, query object is cleared
	/// after this call
	std::string str(query_reset r) { return str(def, r); }

	/// \brief Get built query as a null-terminated C++ string
	///
	/// \param p template query parameters to use, overriding the ones
	/// this object holds, if any
	std::string str(SQLQueryParms& p);

	/// \brief Get built query as a null-terminated C++ string
	///
	/// \param p template query parameters to use, overriding the ones
	/// this object holds, if any
	/// \param r if equal to \c RESET_QUERY, query object is cleared
	/// after this call
	std::string str(SQLQueryParms& p, query_reset r);

	/// \brief Execute a query
	///
	/// Same as execute(), except that it only returns a flag indicating
	/// whether the query succeeded or not.  It is basically a thin
	/// wrapper around the C API function \c mysql_real_query().
	///
	/// \param str the query to execute
	///
	/// \return true if query was executed successfully
	///
	/// \sa execute(), store(), storein(), and use()
	bool exec(const std::string& str);

	/// \brief Execute built-up query
	///
	/// Use one of the execute() overloads if you don't expect the
	/// server to return a result set. For instance, a DELETE query.
	/// The returned ResNSel object contains status information from
	/// the server, such as whether the query succeeded, and if so how
	/// many rows were affected.
	///
	/// This overloaded version of execute() simply executes the query
	/// that you have built up in the object in some way. (For instance,
	/// via the insert() method, or by using the object's stream
	/// interface.)
	///
	/// \return ResNSel status information about the query
	///
	/// \sa exec(), store(), storein(), and use()
	ResNSel execute() { return execute(def); }

	/// \brief Execute query in a C++ string, or substitute string into
	/// a template query and execute it.
	///
	/// \param str If the object represents a compiled template query,
	/// substitutes this string in for the first parameter.  Otherwise,
	/// takes the string as a complete SQL query and executes it.
	ResNSel execute(const SQLString& str);

	/// \brief Execute query in a C string
	///
	/// Executes the query immediately, and returns the results.
	ResNSel execute(const char* str);

	/// \brief Execute query in a known-length string of characters.
	/// This can include null characters.
	///
	/// Executes the query immediately, and returns the results.
	ResNSel execute(const char* str, size_t len);

	/// \brief Execute a query that can return a result set
	/// 
	/// Use one of the use() overloads if memory efficiency is
	/// important.  They return an object that can walk through
	/// the result records one by one, without fetching the entire
	/// result set from the server.  This is superior to store()
	/// when there are a large number of results; store() would have to
	/// allocate a large block of memory to hold all those records,
	/// which could cause problems.
	///
	/// A potential downside of this method is that MySQL database
	/// resources are tied up until the result set is completely
	/// consumed.  Do your best to walk through the result set as
	/// expeditiously as possible.
	///
	/// The name of this method comes from the MySQL C API function
	/// that initiates the retrieval process, \c mysql_use_result().
	/// This method is implemented in terms of that function.
	///
	/// This function has the same set of overloads as execute().
	///
	/// \return ResUse object that can walk through result set serially
	///
	/// \sa exec(), execute(), store() and storein()
	ResUse use() { return use(def); }

	/// \brief Execute query in a C++ string
	///
	/// Executes the query immediately, and returns an object that
	/// lets you walk through the result set one row at a time, in
	/// sequence.  This is more memory-efficient than store().
	ResUse use(const SQLString& str);

	/// \brief Execute query in a C string
	///
	/// Executes the query immediately, and returns an object that
	/// lets you walk through the result set one row at a time, in
	/// sequence.  This is more memory-efficient than store().
	ResUse use(const char* str);

	/// \brief Execute query in a known-length C string
	///
	/// Executes the query immediately, and returns an object that
	/// lets you walk through the result set one row at a time, in
	/// sequence.  This is more memory-efficient than store().
	ResUse use(const char* str, size_t len);

	/// \brief Execute a query that can return a result set
	///
	/// Use one of the store() overloads to execute a query and retrieve
	/// the entire result set into memory.  This is useful if you
	/// actually need all of the records at once, but if not, consider
	/// using one of the use() methods instead, which returns the results
	/// one at a time, so they don't allocate as much memory as store().
	///
	/// You must use store(), storein() or use() for \c SELECT, \c SHOW,
	/// \c DESCRIBE and \c EXPLAIN queries.  You can use these functions
	/// with other query types, but since they don't return a result
	/// set, exec() and execute() are more efficient.
	///
	/// The name of this method comes from the MySQL C API function it
	/// is implemented in terms of, \c mysql_store_result().
	///
	/// This function has the same set of overloads as execute().
	///
	/// \return Result object containing entire result set
	///
	/// \sa exec(), execute(), storein(), and use()
	Result store() { return store(def); }

	/// \brief Execute query in a C++ string
	///
	/// Executes the query immediately, and returns an object that
	/// contains the entire result set.  This is less memory-efficient
	/// than use(), but it lets you have random access to the results.
	Result store(const SQLString& str);

	/// \brief Execute query in a C string
	///
	/// Executes the query immediately, and returns an object that
	/// contains the entire result set.  This is less memory-efficient
	/// than use(), but it lets you have random access to the results.
	Result store(const char* str);

	/// \brief Execute query in a known-length C string
	///
	/// Executes the query immediately, and returns an object that
	/// contains the entire result set.  This is less memory-efficient
	/// than use(), but it lets you have random access to the results.
	Result store(const char* str, size_t len);

	/// \brief Execute a query, and call a functor for each returned row
	///
	/// This method wraps a use() query, calling the given functor for
	/// every returned row.  It is analogous to STL's for_each()
	/// algorithm, but instead of iterating over some range within a
	/// container, it iterates over a result set produced by a query.
	///
	/// \param query the query string
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <typename Function>
	Function for_each(const SQLString& query, Function fn)
	{	
		mysqlpp::ResUse res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				fn(row);
			}
		}

		return fn;
	}

	/// \brief Execute the query, and call a functor for each returned row
	///
	/// Just like for_each(const SQLString&, Function), but it uses
	/// the query string held by the Query object already
	///
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <typename Function>
	Function for_each(Function fn)
	{	
		mysqlpp::ResUse res = use();
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				fn(row);
			}
		}

		return fn;
	}

	/// \brief Run a functor for every row in a table
	///
	/// Just like for_each(Function), except that it builds a
	/// "select * from TABLE" query using the SQL table name from
	/// the SSQLS instance you pass.
	///
	/// \param ssqls the SSQLS instance to get a table name from
	/// \param fn the functor called for each row
	///
	/// \return a copy of the passed functor
	template <class SSQLS, typename Function>
	Function for_each(const SSQLS& ssqls, Function fn)
	{	
		SQLString query("select * from ");
		query += ssqls._table;
		mysqlpp::ResUse res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				fn(row);
			}
		}

		return fn;
	}

	/// \brief Execute a query, conditionally storing each row in a
	/// container
	///
	/// This method wraps a use() query, calling the given functor for
	/// every returned row, and storing the results in the given
	/// sequence container if the functor returns true.
	///
	/// This is analogous to the STL copy_if() algorithm, except that
	/// the source rows come from a database query instead of another
	/// container.  (copy_if() isn't a standard STL algorithm, but only
	/// due to an oversight by the standardization committee.)  This
	/// fact may help you to remember the order of the parameters: the
	/// container is the destination, the query is the source, and the
	/// functor is the predicate; it's just like an STL algorithm.
	///
	/// \param seq the destination container; needs a push_back() method
	/// \param query the query string
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <class Sequence, typename Function>
	Function store_if(Sequence& seq, const SQLString& query, Function fn)
	{	
		mysqlpp::ResUse res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				if (fn(row)) {
					seq.push_back(row);
				}
			}
		}

		return fn;
	}

	/// \brief Pulls every row in a table, conditionally storing each
	/// one in a container
	///
	/// Just like store_if(Sequence&, const SQLString&, Function), but
	/// it uses the SSQLS instance to construct a "select * from TABLE"
	/// query, using the table name field in the SSQLS.
	///
	/// \param seq the destination container; needs a push_back() method
	/// \param ssqls the SSQLS instance to get a table name from
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <class Sequence, class SSQLS, typename Function>
	Function store_if(Sequence& seq, const SSQLS& ssqls, Function fn)
	{	
		SQLString query("select * from ");
		query += ssqls._table;
		mysqlpp::ResUse res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				if (fn(row)) {
					seq.push_back(row);
				}
			}
		}

		return fn;
	}

	/// \brief Execute the query, conditionally storing each row in a
	/// container
	///
	/// Just like store_if(Sequence&, const SQLString&, Function), but
	/// it uses the query string held by the Query object already
	///
	/// \param seq the destination container; needs a push_back() method
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <class Sequence, typename Function>
	Function store_if(Sequence& seq, Function fn)
	{	
		mysqlpp::ResUse res = use();
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				if (fn(row)) {
					seq.push_back(row);
				}
			}
		}

		return fn;
	}

	/// \brief Return next result set, when processing a multi-query
	///
	/// There are two cases where you'd use this function instead of
	/// the regular store() functions.
	/// 
	/// First, when handling the result of executing multiple queries
	/// at once.  (See <a
	/// href="http://dev.mysql.com/doc/mysql/en/c-api-multiple-queries.html">this
	/// page</a> in the MySQL documentation for details.) 
	///
	/// Second, when calling a stored procedure, MySQL can return the
	/// result as a set of results.
	///
	/// In either case, you must consume all results before making
	/// another MySQL query, even if you don't care about the remaining
	/// results or result sets.
	///
	/// As the MySQL documentation points out, you must set the
	/// MYSQL_OPTION_MULTI_STATEMENTS_ON flag on the connection in order
	/// to use this feature.  See Connection::set_option().
	///
	/// Multi-queries only exist in MySQL v4.1 and higher.  Therefore,
	/// this function just wraps store() when built against older API
	/// libraries.
	///
	/// \return Result object containing the next result set.
	Result store_next();

	/// \brief Return whether more results are waiting for a multi-query
	/// or stored procedure response.
	///
	/// If this function returns true, you must call store_next() to
	/// fetch the next result set before you can execute more queries.
	///
	/// Wraps mysql_more_results() in the MySQL C API.  That function
	/// only exists in MySQL v4.1 and higher.  Therefore, this function
	/// always returns false when built against older API libraries.
	///
	/// \return true if another result set exists
	bool more_results();

	/// \brief Execute a query, storing the result set in an STL
	/// sequence container.
	///
	/// This function works much like store() from the caller's
	/// perspective, because it returns the entire result set at once.
	/// It's actually implemented in terms of use(), however, so that
	/// memory for the result set doesn't need to be allocated twice.
	///
	/// There are many overloads for this function, pretty much the same
	/// as for execute(), except that there is a Container parameter at
	/// the front of the list.  So, you can pass a container and a query
	/// string, or a container and template query parameters.
	///
	/// \param con any STL sequence container, such as \c std::vector
	/// \param r whether the query automatically resets after being used
	///
	/// \sa exec(), execute(), store(), and use()
	template <class Sequence>
	void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
	{
		storein_sequence(con, def, r);
	}

	/// \brief Execute a query, storing the result set in an STL
	/// associative container.
	///
	/// The same thing as storein_sequence(), except that it's used with
	/// associative STL containers, such as \c std::set.  Other than
	/// that detail, that method's comments apply equally well to this
	/// one.
	template <class Set>
	void storein_set(Set& con, query_reset r = RESET_QUERY)
	{
		storein_set(con, def, r);
	}

	/// \brief Execute a query, and store the entire result set
	/// in an STL container.
	///
	/// This is a set of specialized template functions that call either
	/// storein_sequence() or storein_set(), depending on the type of
	/// container you pass it. It understands \c std::vector, \c deque,
	/// \c list, \c slist (a common C++ library extension), \c set,
	/// and \c multiset.
	///
	/// Like the functions it wraps, this is actually an overloaded set
	/// of functions. See the other functions' documentation for details.
	///
	/// Use this function if you think you might someday switch your
	/// program from using a set-associative container to a sequence
	/// container for storing result sets, or vice versa.
	///
	/// See exec(), execute(), store(), and use() for alternative
	/// query execution mechanisms.
	template <class Container>
	void storein(Container& con, query_reset r = RESET_QUERY)
	{
		storein(con, def, r);
	}

	/// \brief Specialization of storein_sequence() for \c std::vector
	template <class T>
	void storein(std::vector<T>& con, const char* s)
	{
		storein_sequence(con, s);
	}

	/// \brief Specialization of storein_sequence() for \c std::deque
	template <class T>
	void storein(std::deque<T>& con, const char* s)
	{
		storein_sequence(con, s);
	}

	/// \brief Specialization of storein_sequence() for \c std::list
	template <class T>
	void storein(std::list<T>& con, const char* s)
	{
		storein_sequence(con, s);
	}

#if defined(HAVE_EXT_SLIST)
	/// \brief Specialization of storein_sequence() for g++ STL
	/// extension \c slist
	template <class T>
	void storein(__gnu_cxx::slist<T>& con, const char* s)
	{
		storein_sequence(con, s);
	}
#elif defined(HAVE_GLOBAL_SLIST)
	/// \brief Specialization of storein_sequence() for STL
	/// extension \c slist
	///
	/// This is primarily for older versions of g++, which put \c slist
	/// in the global namespace.  This is a common language extension,
	/// so this may also work for other compilers.
	template <class T>
	void storein(slist<T>& con, const char* s)
	{
		storein_sequence(con, s);
	}
#elif defined(HAVE_STD_SLIST)
	/// \brief Specialization of storein_sequence() for STL
	/// extension \c slist
	///
	/// This is for those benighted compilers that include an \c slist
	/// implementation, but erroneously put it in the \c std namespace!
	template <class T>
	void storein(std::slist<T>& con, const char* s)
	{
		storein_sequence(con, s);
	}
#endif

	/// \brief Specialization of storein_set() for \c std::set
	template <class T>
	void storein(std::set<T>& con, const char* s)
	{
		storein_set(con, s);
	}

	/// \brief Specialization of storein_set() for \c std::multiset
	template <class T>
	void storein(std::multiset<T>& con, const char* s)
	{
		storein_set(con, s);
	}

	/// \brief Replace an existing row's data with new data.
	///
	/// This function builds an UPDATE SQL query using the new row data
	/// for the SET clause, and the old row data for the WHERE clause.
	/// One uses it with MySQL++'s Specialized SQL Structures mechanism.
	///
	/// \param o old row
	/// \param n new row
	///
	/// \sa insert(), replace()
	template <class T>
	Query& update(const T& o, const T& n)
	{
		reset();

		// Cast required for VC++ 2003 due to error in overloaded operator
		// lookup logic.  For an explanation of the problem, see:
		// http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"UPDATE " << o.table() << " SET " << n.equal_list() <<
				" WHERE " << o.equal_list(" AND ", sql_use_compare);
		return *this;
	}

	/// \brief Insert a new row.
	///
	/// This function builds an INSERT SQL query.  One uses it with
	/// MySQL++'s Specialized SQL Structures mechanism.
	///
	/// \param v new row
	///
	/// \sa replace(), update()
	template <class T>
	Query& insert(const T& v)
	{
		reset();

		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"INSERT INTO " << v.table() << " (" <<
				v.field_list() << ") VALUES (" <<
				v.value_list() << ')';
		return *this;
	}

	/// \brief Insert multiple new rows.
	///
	/// Builds an INSERT SQL query using items from a range within an
	/// STL container.  Insert the entire contents of the container by
	/// using the begin() and end() iterators of the container as
	/// parameters to this function.
	///
	/// \param first iterator pointing to first element in range to
	///    insert
	/// \param last iterator pointing to one past the last element to
	///    insert
	///
	/// \sa replace(), update()
	template <class Iter>
	Query& insert(Iter first, Iter last)
	{
		reset();
		if (first == last) {
			return *this;	// empty set!
		}
		
		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"INSERT INTO " << first->table() << " (" <<
				first->field_list() << ") VALUES (" <<
				first->value_list() << ')';

		Iter it = first + 1;
		while (it != last) {
			MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
			++it;
		}

		return *this;
	}

	/// \brief Insert new row unless there is an existing row that
	/// matches on a unique index, in which case we replace it.
	///
	/// This function builds a REPLACE SQL query.  One uses it with
	/// MySQL++'s Specialized SQL Structures mechanism.
	///
	/// \param v new row
	///
	/// \sa insert(), update()
	template <class T>
	Query& replace(const T& v)
	{
		reset();

		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"REPLACE INTO " << v.table() << " (" <<
				v.field_list() << ") VALUES (" << v.value_list() << ')';
		return *this;
	}

	/// \brief Return true if the last query was successful
	operator bool() { return success(); }

	/// \brief Return true if the last query failed
	bool operator !() { return !success(); }

#if !defined(DOXYGEN_IGNORE)
	// Declare the remaining overloads.  These are hidden down here partly
	// to keep the above code clear, but also so that we may hide them
	// from Doxygen, which gets confused by macro instantiations that look
	// like method declarations.
	mysql_query_define0(std::string, preview)
	mysql_query_define0(std::string, str)
	mysql_query_define1(ResNSel, execute)
	mysql_query_define1(Result, store)
	mysql_query_define1(ResUse, use)
	mysql_query_define2(storein_sequence)
	mysql_query_define2(storein_set)
	mysql_query_define2(storein)
#endif // !defined(DOXYGEN_IGNORE)

	/// \brief The default template parameters
	///
	/// Used for filling in parameterized queries.
	SQLQueryParms def;

private:
	friend class SQLQueryParms;

	/// \brief Connection to send queries through
	Connection* conn_;

	/// \brief If true, last query succeeded
	bool success_;

	/// \brief List of template query parameters
	std::vector<SQLParseElement> parse_elems_;

	/// \brief Maps template parameter position values to the
	/// corresponding parameter name.
	std::vector<std::string> parsed_names_;

	/// \brief Maps template parameter names to their position value.
	std::map<std::string, short int> parsed_nums_;

	/// \brief String buffer for storing assembled query
	std::stringbuf sbuffer_;

	//// Internal support functions
	my_ulonglong affected_rows() const;
	my_ulonglong insert_id();
	std::string info();
	char* preview_char();

	/// \brief Process a parameterized query list.
	void proc(SQLQueryParms& p);

	// Locking mechanism
	bool lock();
	void unlock();

	SQLString* pprepare(char option, SQLString& S, bool replace = true);
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

template <class Seq>
void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
{
	r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
	storein_sequence(seq, str(p, r).c_str());
}


template <class Sequence>
void Query::storein_sequence(Sequence& con, const char* s)
{
	ResUse result = use(s);
	while (1) {
		MYSQL_ROW d = mysql_fetch_row(result.raw_result());
		if (!d)
			break;
		Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
				true);
		if (!row)
			break;
		con.push_back(typename Sequence::value_type(row));
	}
}


template <class Set>
void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
{
	r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
	storein_set(sett, str(p, r).c_str());
}


template <class Set>
void Query::storein_set(Set& con, const char* s)
{
	ResUse result = use(s);
	while (1) {
		MYSQL_ROW d = mysql_fetch_row(result.raw_result());
		if (!d)
			return;
		Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
				true);
		if (!row)
			break;
		con.insert(typename Set::value_type(row));
	}
}


template <class T>
void Query::storein(T& con, SQLQueryParms& p, query_reset r)
{
	r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
	storein(con, str(p, r).c_str());
}


#endif // !defined(DOXYGEN_IGNORE)

} // end namespace mysqlpp

#endif

Deleted lib/querydef.h.
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






















































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This file is generated by the Perl script querydef.pl. Please do 
// not modify this file directly. Change the script instead.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#ifndef MYSQLPP_QUERYDEF_H
#define MYSQLPP_QUERYDEF_H

#define mysql_query_define0(RETURN, FUNC) \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23); } \
	RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23, const SQLString& arg24) \
		{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23 << arg24); } \

#define mysql_query_define1(RETURN, FUNC) \
	RETURN FUNC(SQLQueryParms& p); \
	mysql_query_define0(RETURN, FUNC)

#define mysql_query_define2(FUNC) \
	template <class T> void FUNC(T& container, const char* str); \
	template <class T> void FUNC(T& container, SQLQueryParms& p, \
  		query_reset r = RESET_QUERY); \
	template <class T> void FUNC(T& container, const SQLString& arg0) \
		{ FUNC(container, SQLQueryParms() << arg0); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23); } \
	template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23, const SQLString& arg24) \
		{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23 << arg24); } \

#endif // !defined(MYSQLPP_QUERYDEF_H)
Deleted lib/querydef.pl.
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








































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/usr/bin/perl -w

########################################################################
# querydef.pl - Generates querydef.h, which defines a number of macros
#	used in query.h that differ only in the number of arguments.  That
#	number limits the number of parameters a MySQL++ template query can
#	accept.  This value can be changed from its default, below.
#
# Copyright (c) 2006-2007 by Educational Technology Resources, Inc.
# Others may also hold copyrights on code in this file.  See the CREDITS
# file in the top directory of the distribution for details.
#
# This file is part of MySQL++.
#
# MySQL++ is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# MySQL++ is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with MySQL++; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
########################################################################


# The number of parameters a template query can accept.  Make this value
# larger only at need, as it adds code to the library proportionally.
# You should not reduce this value if programs you did not write may
# link to the library, as that would constitute an ABI breakage.
my $max_parameters = 25;


# No user-serviceable parts below.

use strict;

open (OUT, ">querydef.h");

print OUT << "---";
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This file is generated by the Perl script querydef.pl. Please do 
// not modify this file directly. Change the script instead.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#ifndef MYSQLPP_QUERYDEF_H
#define MYSQLPP_QUERYDEF_H

---

## Build mysql_query_define0 macro
print OUT "#define mysql_query_define0(RETURN, FUNC) \\\n";
for (my $i = 1; $i < $max_parameters; ++$i) {
	print OUT "\tRETURN FUNC(";
	for (my $j = 0; $j < $i + 1; ++$j) {
		print OUT 'const SQLString& arg', $j;
		print OUT ', ' unless $j == $i;
	}
	print OUT ") \\\n";

	print OUT "\t\t{ return FUNC(SQLQueryParms()";
	for (my $j = 0; $j < $i + 1; ++$j) {
		print OUT ' << arg', $j;
	}
	print OUT "); } \\\n";
}

## Add mysql_query_define1 macro
print OUT << "---";

#define mysql_query_define1(RETURN, FUNC) \\
	RETURN FUNC(SQLQueryParms& p); \\
	mysql_query_define0(RETURN, FUNC)
---

## Add mysql_query_define2 macro
print OUT << "---";

#define mysql_query_define2(FUNC) \\
	template <class T> void FUNC(T& container, const char* str); \\
	template <class T> void FUNC(T& container, SQLQueryParms& p, \\
  		query_reset r = RESET_QUERY); \\
---
for (my $i = 0; $i < $max_parameters; ++$i) {
	print OUT "\ttemplate <class T> void FUNC(T& container";
	for (my $j = 0; $j < $i + 1; ++$j) {
		print OUT ', const SQLString& arg', $j;
	}
	print OUT ") \\\n";
	print OUT "\t\t{ FUNC(container, SQLQueryParms()";
	for (my $j = 0; $j < $i + 1; ++$j) {
		print OUT ' << arg', $j;
	}
	print OUT "); } \\\n";
}

## That's all, folks!
print OUT "\n#endif // !defined(MYSQLPP_QUERYDEF_H)\n";

Deleted lib/resiter.h.
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






















































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file resiter.h
/// \brief Declares templates for adapting existing classes to
/// be iteratable random-access containers.
///
/// The file name seems to tie it to the mysqlpp::Result class, which
/// is so adapted, but these templates are also used to adapt the
/// mysqlpp::Fields and mysqlpp::Row classes.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_RESITER_H
#define MYSQLPP_RESITER_H

#include "common.h"

#include <iterator>

namespace mysqlpp {

template <class OnType, class ReturnType, class SizeType,
	class DiffType> class subscript_iterator;

/// \brief A base class that one derives from to become a random
/// access container, which can be accessed with subscript notation.
///
/// OnType must have the member functions \c operator[](SizeType) and
// \c size() defined for it.

template <class OnType,
		class ValueType,
		class ReturnType = const ValueType&,
		class SizeType = unsigned int,
		class DiffType = int>
class const_subscript_container
{
public:
	typedef const_subscript_container<OnType, ValueType, ReturnType,
			SizeType, DiffType> this_type; ///< this object's type
	typedef subscript_iterator<const this_type, ReturnType, SizeType,
			DiffType> iterator;			///< mutable iterator type
	typedef iterator const_iterator;	///< constant iterator type
	typedef const std::reverse_iterator<iterator>
			reverse_iterator;			///< mutable reverse iterator type
	typedef const std::reverse_iterator<const_iterator>
			const_reverse_iterator;		///< const reverse iterator type

	typedef ValueType value_type;		///< type of data stored in container
	typedef value_type& reference;		///< reference to value_type
	typedef value_type& const_reference;///< const ref to value_type
	typedef value_type* pointer;		///< pointer to value_type
	typedef value_type* const_pointer;	///< const pointer to value_type

	typedef DiffType difference_type;	///< for index differences
	typedef SizeType size_type;			///< for returned sizes

	/// \brief Destroy object
	virtual ~const_subscript_container() { }

	/// \brief Return count of elements in container
	virtual size_type size() const = 0;	

	/// \brief Return element at given index in container
	virtual ReturnType at(SizeType i) const = 0;

	/// \brief Return maximum number of elements that can be stored
	/// in container without resizing.
	size_type max_size() const { return size(); }

	/// \brief Returns true if container is empty
	bool empty() const { return size() == 0; }

	/// \brief Return iterator pointing to first element in the
	/// container
	iterator begin() const { return iterator(this, 0); }

	/// \brief Return iterator pointing to one past the last element
	/// in the container
	iterator end() const { return iterator(this, size()); }

	/// \brief Return reverse iterator pointing to first element in the
	/// container
	reverse_iterator rbegin() const { return reverse_iterator(end()); }

	/// \brief Return reverse iterator pointing to one past the last
	/// element in the container
	reverse_iterator rend() const { return reverse_iterator(begin()); }
};


/// \brief Iterator that can be subscripted.
///
/// This is the type of iterator used by the const_subscript_container
/// template.

template <class OnType, class ReturnType, class SizeType,
		class DiffType>
class subscript_iterator : public std::iterator<ReturnType, SizeType>
{
public:
	/// \brief Default constructor
	subscript_iterator() { }

	/// \brief Create iterator given the container and a position
	/// within it.
	subscript_iterator(OnType* what, SizeType pos)
	{
		d_ = what;
		i_ = pos;
	}

	/// \brief Return true if given iterator points to the same
	/// container and the same position within the container.
	bool operator ==(const subscript_iterator& j) const
	{
		return (d_ == j.d_ && i_ == j.i_);
	}
	
	/// \brief Return true if given iterator is different from this
	/// one, but points to the same container.
	bool operator !=(const subscript_iterator& j) const
	{
		return (d_ == j.d_ && i_ != j.i_);
	}
	
	/// \brief Return true if the given iterator points to the same
	/// container as this one, and that this iterator's position is
	/// less than the given iterator's.
	bool operator <(const subscript_iterator& j) const
	{
		return (d_ == j.d_ && i_ < j.i_);
	}
	
	/// \brief Return true if the given iterator points to the same
	/// container as this one, and that this iterator's position is
	/// greater than the given iterator's.
	bool operator >(const subscript_iterator & j) const
	{
		return (d_ == j.d_ && i_ > j.i_);
	}
	
	/// \brief Return true if the given iterator points to the same
	/// container as this one, and that this iterator's position is
	/// less than or equal to the given iterator's.
	bool operator <=(const subscript_iterator & j) const
	{
		return (d_ == j.d_ && i_ <= j.i_);
	}
	
	/// \brief Return true if the given iterator points to the same
	/// container as this one, and that this iterator's position is
	/// greater than or equal to the given iterator's.
	bool operator >=(const subscript_iterator & j) const
	{
		return (d_ == j.d_ && i_ >= j.i_);
	}
	
	/// \brief Dereference the iterator, returning a copy of the
	/// pointed-to element within the container.
	ReturnType operator *() const { return d_->at(i_); }
	
	/// \brief Return a copy of the element at the given position
	/// within the container.
	ReturnType operator [](SizeType n) const { return d_->at(n); }
	
	/// \brief Move the iterator to the next element, returning an
	/// iterator to that element
	subscript_iterator& operator ++() { ++i_; return *this; }

	/// \brief Move the iterator to the next element, returning an
	/// iterator to the element we were pointing at before the change
	subscript_iterator operator ++(int)
	{
		subscript_iterator tmp = *this;
		++i_;
		return tmp;
	}

	/// \brief Move the iterator to the previous element, returning an
	/// iterator to that element
	subscript_iterator& operator --()
	{
		--i_;
		return *this;
	}

	/// \brief Move the iterator to the previous element, returning an
	/// iterator to the element we were pointing at before the change
	subscript_iterator operator --(int)
	{
		subscript_iterator tmp = *this;
		--i_;
		return tmp;
	}

	/// \brief Advance iterator position by \c n
	subscript_iterator& operator +=(SizeType n)
	{
		i_ += n;
		return *this;
	}

	/// \brief Return an iterator \c n positions beyond this one
	subscript_iterator operator +(SizeType n) const
	{
		subscript_iterator tmp = *this;
		tmp.i_ += n;
		return tmp;
	}
	
	/// \brief Move iterator position back by \c n
	subscript_iterator& operator -=(SizeType n)
	{
		i_ -= n;
		return *this;
	}

	/// \brief Return an iterator \c n positions before this one
	subscript_iterator operator -(SizeType n) const
	{
		subscript_iterator tmp = *this;
		tmp.i_ -= n;
		return tmp;
	}
	
	/// \brief Return an iterator \c n positions before this one
	DiffType operator -(const subscript_iterator& j) const
	{
		if (d_ == j.d_) {
			return static_cast<SizeType>(i_) - j.i_;
		}
		return 0;
	}

private:
	SizeType i_;
	OnType* d_;
};


#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

template <class OnType, class ReturnType, class SizeType,
		class DiffType> 
inline subscript_iterator<OnType, ReturnType, SizeType, DiffType>
operator +(SizeType x,
		const subscript_iterator <OnType, ReturnType, SizeType, DiffType>& y)
{
	return y + x;
}

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace mysqlpp

#endif
Deleted lib/result.cpp.
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















































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 result.cpp - Implements the Result, ResNSel, and ResUse classes.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "result.h"

#include "connection.h"

namespace mysqlpp {

ResNSel::ResNSel(Connection* q) :
success(q->success()),
insert_id(q->insert_id()),
rows(q->affected_rows()),
info(q->info())
{
}


ResUse::ResUse(MYSQL_RES* result, Connection* c, bool te) :
OptionalExceptions(te),
conn_(c),
initialized_(false),
names_(0),
types_(0),
fields_(this)
{
	if (!result) {
		result_ = 0;
		types_ = 0;
		names_ = 0;
		return;
	}
	result_ = result;
	names_ = new FieldNames(this);
	if (names_) {
		types_ = new FieldTypes(this);
	}
	table_ = fields(0).table;
	initialized_ = true;
}


ResUse::~ResUse()
{
	purge();
}


void
ResUse::copy(const ResUse& other)
{
	if (initialized_) {
		purge();
	}

	set_exceptions(other.throw_exceptions());

	if (!other.result_) {
		result_ = 0;
		types_ = 0;
		names_ = 0;
		initialized_ = other.initialized_;
		return;
	}

	result_ = other.result_;
	fields_ = Fields(this);

	if (other.names_) {
		names_ = new FieldNames(*other.names_);
	}
	else {
		names_ = 0;
	}
	
	if (other.types_) {
		types_ = new FieldTypes(*other.types_);
	}
	else {
		types_ = 0;
	}

	table_ = other.table_;

	conn_ = other.conn_;
	initialized_ = true;
}


int
ResUse::field_num(const std::string& i) const
{
	if (!names_) {
		names_ = new FieldNames(this);
	}

	size_t index = (*names_)[i];
	if ((index >= names_->size()) && throw_exceptions()) {
		throw BadFieldName(i.c_str());
	}
	
	return int(index);
}


std::string&
ResUse::field_name(int i)
{
	if (!names_) {
		names_ = new FieldNames(this);
	}
	return (*names_)[i];
}


const std::string&
ResUse::field_name(int i) const
{
	if (!names_) {
		names_ = new FieldNames(this);
	}
	return (*names_)[i];
}


FieldNames&
ResUse::field_names()
{
	if (!names_) {
		names_ = new FieldNames(this);
	}
	return *names_;
}


const FieldNames&
ResUse::field_names() const
{
	if (!names_) {
		names_ = new FieldNames(this);
	}
	return *names_;
}


void
ResUse::reset_field_names()
{
	delete names_;
	names_ = 0;
	names_ = new FieldNames(this);
}


mysql_type_info&
ResUse::field_type(int i)
{
	if (!types_) {
		types_ = new FieldTypes(this);
	}
	return (*types_)[i];
}


const mysql_type_info&
ResUse::field_type(int i) const
{
	if (!types_) {
		types_ = new FieldTypes(this);
	}
	return (*types_)[i];
}


FieldTypes&
ResUse::field_types()
{
	if (!types_) {
		types_ = new FieldTypes(this);
	}
	return *types_;
}


const FieldTypes&
ResUse::field_types() const
{
	if (!types_) {
		types_ = new FieldTypes(this);
	}
	return *types_;
}


void
ResUse::reset_field_types()
{
	delete types_;
	types_ = 0;
	types_ = new FieldTypes(this);
}


ResUse&
ResUse::operator =(const ResUse& other)
{
	if (this == &other) {
		return *this;
	}
	copy(other);
	other.result_ = 0;
	return *this;
}

} // end namespace mysqlpp

Deleted lib/result.h.
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
























































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file result.h
/// \brief Declares classes for holding SQL query result sets.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_RESULT_H
#define MYSQLPP_RESULT_H

#include "common.h"

#include "exceptions.h"
#include "fields.h"
#include "field_names.h"
#include "field_types.h"
#include "noexceptions.h"
#include "resiter.h"
#include "row.h"

#include <map>
#include <set>
#include <string>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT Connection;
#endif

/// \brief A basic result set class, for use with "use" queries.
///
/// A "use" query is one where you make the query and then process just
/// one row at a time in the result instead of dealing with them all as
/// a single large chunk.  (The name comes from the MySQL C API function
/// that initiates this action, \c mysql_use_result().)  By calling
/// fetch_row() until it throws a mysqlpp::BadQuery exception (or an
/// empty row if exceptions are disabled), you can process the result
/// set one row at a time.

class MYSQLPP_EXPORT ResUse : public OptionalExceptions
{
public:
	/// \brief Default constructor
	ResUse() :
	OptionalExceptions(),
	conn_(0),
	result_(0),
	initialized_(false),
	names_(0),
	types_(0),
	fields_(this)
	{
	}
	
	/// \brief Create the object, fully initialized
	ResUse(MYSQL_RES* result, Connection* c = 0, bool te = true);
	
	/// \brief Create a copy of another ResUse object
	ResUse(const ResUse& other) :
	OptionalExceptions(),
	initialized_(false)
	{
		copy(other);
		other.result_ = 0;
	}
	
	/// \brief Destroy object
	virtual ~ResUse();

	/// \brief Copy another ResUse object's data into this object
	ResUse& operator =(const ResUse& other);

	/// \brief Return raw MySQL C API result set
	MYSQL_RES* raw_result()
	{
		return result_;
	}

	/// \brief Wraps mysql_fetch_row() in MySQL C API.
	///
	/// This is not a thin wrapper. It does a lot of error checking before
	/// returning the mysqlpp::Row object containing the row data.
	Row fetch_row()
	{
		if (!result_) {
			if (throw_exceptions()) {
				throw BadQuery("Results not fetched");
			}
			else {
				return Row();
			}
		}
		MYSQL_ROW row = mysql_fetch_row(result_);
		unsigned long* length = mysql_fetch_lengths(result_);
		if (!row || !length) {
			if (throw_exceptions()) {
				throw EndOfResults();
			}
			else {
				return Row();
			}
		}
		return Row(row, this, length, throw_exceptions());
	}

	/// \brief Wraps mysql_fetch_lengths() in MySQL C API.
	unsigned long *fetch_lengths() const
	{
		return mysql_fetch_lengths(result_);
	}

	/// \brief Wraps mysql_fetch_field() in MySQL C API.
	Field& fetch_field() const
	{
		return *mysql_fetch_field(result_);
	}

	/// \brief Wraps mysql_field_seek() in MySQL C API.
	void field_seek(int field)
	{
		mysql_field_seek(result_, field);
	}

	/// \brief Wraps mysql_num_fields() in MySQL C API.
	int num_fields() const
	{
		return mysql_num_fields(result_);
	}
	
	/// \brief Documentation needed!
	void parent_leaving()
	{
		conn_ = 0;
	}

	/// \brief Free all resources held by the object.
	///
	/// This class's destructor is little more than a call to purge(),
	/// so you can think of this as a way to re-use a ResUse object,
	/// to avoid having to completely re-create it.
	void purge()
	{
		if (result_) {
			mysql_free_result(result_);
			result_ = 0;
		}

		delete names_;
		names_ = 0;

		delete types_;
		types_ = 0;

		table_.erase();
	}

	/// \brief Return true if we have a valid result set
	///
	/// This operator is primarily used to determine if a query was
	/// successful:
	///
	/// \code
	///   Query q("....");
	///   if (q.use()) {
	///       ...
	/// \endcode
	///
	/// Query::use() returns a ResUse object, and it won't contain a
	/// valid result set if the query failed.
	operator bool() const
	{
		return result_;
	}
	
	/// \brief Return the number of columns in the result set.
	unsigned int columns() const
	{
		return num_fields();
	}

	/// \brief Get the name of table that the result set comes from.
	std::string& table()
	{
		return table_;
	}

	/// \brief Return the name of the table
	///
	/// This is only valid 
	const std::string& table() const
	{
		return table_;
	}

	/// \brief Get the index of the named field.
	///
	/// This is the inverse of field_name().
	int field_num(const std::string&) const;

	/// \brief Get the name of the field at the given index.
	///
	/// This is the inverse of field_num().
	std::string& field_name(int);

	/// \brief Get the name of the field at the given index.
	const std::string& field_name(int) const;

	/// \brief Get the names of the fields within this result set.
	FieldNames& field_names();

	/// \brief Get the names of the fields within this result set.
	const FieldNames& field_names() const;

	/// \brief Reset the names in the field list to their original
	/// values.
	void reset_field_names();

	/// \brief Get the MySQL type for a field given its index.
	mysql_type_info& field_type(int i);

	/// \brief Get the MySQL type for a field given its index.
	const mysql_type_info& field_type(int) const;

	/// \brief Get a list of the types of the fields within this
	/// result set.
	FieldTypes& field_types();

	/// \brief Get a list of the types of the fields within this
	/// result set.
	const FieldTypes& field_types() const;

	/// \brief Reset the field types to their original values.
	void reset_field_types();

	/// \brief Alias for field_num()
	int names(const std::string & s) const { return field_num(s); }

	/// \brief Alias for field_name()
	std::string& names(int i) { return field_name(i); }

	/// \brief Alias for field_name()
	const std::string& names(int i) const { return field_name(i); }

	/// \brief Alias for field_names()
	FieldNames& names() { return field_names(); }

	/// \brief Alias for field_names()
	const FieldNames& names() const { return field_names(); }

	/// \brief Alias for reset_field_names()
	void reset_names() { reset_field_names(); }

	/// \brief Alias for field_type()
	mysql_type_info& types(int i) { return field_type(i); }

	/// \brief Alias for field_type()
	const mysql_type_info& types(int i) const { return field_type(i); }

	/// \brief Alias for field_types()
	FieldTypes& types() { return field_types(); }

	/// \brief Alias for field_types()
	const FieldTypes& types() const { return field_types(); }

	/// \brief Alias for reset_field_types()
	void reset_types() { reset_field_types(); }

	/// \brief Get the underlying Fields structure.
	const Fields& fields() const { return fields_; }

	/// \brief Get the underlying Field structure given its index.
	const Field& fields(unsigned int i) const { return fields_.at(i); }
	
	/// \brief Returns true if the other ResUse object shares the same
	/// underlying C API result set as this one.
	///
	/// This works because the underlying result set is stored as a
	/// pointer, and thus can be copied and then compared.
	bool operator ==(const ResUse& other) const
	{
		return result_ == other.result_;
	}
	
	/// \brief Returns true if the other ResUse object has a different
	/// underlying C API result set from this one.
	bool operator !=(const ResUse& other) const
	{
		return result_ != other.result_;
	}

protected:
	Connection* conn_;			///< server result set comes from
	mutable MYSQL_RES* result_;	///< underlying C API result set
	bool initialized_;			///< if true, object is fully initted
	mutable FieldNames* names_;	///< list of field names in result
	mutable FieldTypes* types_;	///< list of field types in result
	Fields fields_;				///< list of fields in result
	std::string table_;			///< table result set comes from

	/// \brief Copy another ResUse object's contents into this one.
	///
	/// Self-copy is not allowed.
	void copy(const ResUse& other);
};


/// \brief This class manages SQL result sets. 
///
/// Objects of this class are created to manage the result of "store"
/// queries, where the result set is handed to the program as single
/// block of row data. (The name comes from the MySQL C API function
/// \c mysql_store_result() which creates these blocks of row data.)
///
/// This class is a random access container (in the STL sense) which
/// is neither less-than comparable nor assignable.  This container
/// provides a reverse random-access iterator in addition to the normal
/// forward one.

class MYSQLPP_EXPORT Result : public ResUse,
		public const_subscript_container<Result, Row, const Row>
{
public:
	/// \brief Default constructor
	Result()
	{
	}
	
	/// \brief Fully initialize object
	Result(MYSQL_RES* result, bool te = true) :
	ResUse(result, 0, te)
	{
	}

	/// \brief Initialize object as a copy of another Result object
	Result(const Result& other) :
	ResUse(other),
	const_subscript_container<Result, Row, const Row>() // no copying here
	{
		conn_ = 0;
	}

	/// \brief Destroy result set
	virtual ~Result() { }

	/// \brief Wraps mysql_fetch_row() in MySQL C API.
	///
	/// This is simply the const version of the same function in our
	/// \link mysqlpp::ResUse parent class \endlink . Why this cannot
	/// actually \e be in our parent class is beyond me.
	const Row fetch_row() const
	{
		if (!result_) {
			if (throw_exceptions()) {
				throw BadQuery("Results not fetched");
			}
			else {
				return Row();
			}
		}
		MYSQL_ROW row = mysql_fetch_row(result_);
		unsigned long* length = mysql_fetch_lengths(result_);
		if (!row || !length) {
			if (throw_exceptions()) {
				throw EndOfResults();
			}
			else {
				return Row();
			}
		}
		return Row(row, this, length, throw_exceptions());
	}

	/// \brief Wraps mysql_num_rows() in MySQL C API.
	my_ulonglong num_rows() const
	{
		if (initialized_)
			return mysql_num_rows(result_);
		else
			return 0;
	}

	/// \brief Wraps mysql_data_seek() in MySQL C API.
	void data_seek(uint offset) const
	{
		mysql_data_seek(result_, offset);
	}

	/// \brief Alias for num_rows(), only with different return type.
	size_type size() const
	{
		return size_type(num_rows());
	}

	/// \brief Alias for num_rows(), only with different return type.
	size_type rows() const
	{
		return size_type(num_rows());
	}

	/// \brief Get the row with an offset of i.
	const Row at(size_type i) const
	{
		data_seek(i);
		return fetch_row();
	}
};


/// \brief Swaps two ResUse objects
inline void swap(ResUse& x, ResUse& y)
{
	ResUse tmp = x;
	x = y;
	y = tmp;
}

/// \brief Swaps two Result objects
inline void swap(Result& x, Result& y)
{
	Result tmp = x;
	x = y;
	y = tmp;
}

/// \brief Holds the information on the success of queries that
/// don't return any results.
class MYSQLPP_EXPORT ResNSel
{
public:
	bool success;			///< if true, query was successful
	my_ulonglong insert_id;	///< last value used for AUTO_INCREMENT field
	my_ulonglong rows;		///< number of rows affected
	std::string info;		///< additional info about query result

	ResNSel() :
	success(false)
	{
	}

	/// \brief Initialize object
	ResNSel(Connection* q);

	/// \brief Returns true if the query was successful
	operator bool() { return success; }
};


} // end namespace mysqlpp

#endif
Deleted lib/row.cpp.
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


























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 row.cpp - Implements the Row class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "row.h"
#include "result.h"
#include "exceptions.h"

namespace mysqlpp {

Row::Row(const MYSQL_ROW& d, const ResUse* r,
		unsigned long* jj, bool te) :
OptionalExceptions(te),
res_(r),
initialized_(false)
{
	if (!d || !r) {
		if (throw_exceptions()) {
			throw BadQuery("ROW or RES is NULL");
		}
		else {
			return;
		}
	}

	data_.clear();
	is_nulls_.clear();
	initialized_ = true;

	for (size_type i = 0; i < size(); ++i) {
		data_.insert(data_.end(),
				(d[i] ?  std::string(d[i], jj[i]) : std::string("NULL")));
		is_nulls_.insert(is_nulls_.end(), d[i] ? false : true);
	}
}


Row::~Row()
{
	data_.clear();
	is_nulls_.clear();
	initialized_ = false;
}


Row::size_type Row::size() const
{
	return res_->num_fields();
}

const ColData Row::at(size_type i) const
{
	if (initialized_) {
		const std::string& s = data_.at(i);
		return ColData(s.data(), s.length(), res_->types(i),
				is_nulls_[i]);
	}
	else {
		if (throw_exceptions())
			throw std::out_of_range("Row not initialized");
		else
			return ColData();
	}
}

const ColData Row::operator [](const char* field) const
{
	size_type si = res_->field_num(std::string(field));
	if (si < size()) {
		return at(si);
	}
	else {
		throw BadFieldName(field);
	}
}


value_list_ba<FieldNames, do_nothing_type0>
Row::field_list(const char* d) const
{
	return value_list_ba<FieldNames, do_nothing_type0>
			(parent().names(), d, do_nothing);
}

template <class Manip>
value_list_ba<FieldNames, Manip>
Row::field_list(const char *d, Manip m) const
{
	return value_list_ba<FieldNames, Manip>(parent().names(), d, m);
}

template <class Manip>
value_list_b<FieldNames, Manip>
Row::field_list(const char *d, Manip m, const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const char* d, const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, d, quote);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, ",", quote);
}

template <class Manip> value_list_b<FieldNames, Manip>
Row::field_list(const char* d, Manip m, bool t0, bool t1, bool t2,
		bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
		bool ta, bool tb, bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const char *d, bool t0, bool t1, bool t2, bool t3,
		bool t4, bool t5, bool t6, bool t7, bool t8, bool t9, bool ta,
		bool tb, bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, d, quote);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(bool t0, bool t1, bool t2, bool t3, bool t4, bool t5,
		bool t6, bool t7, bool t8, bool t9, bool ta, bool tb,
		bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, ",", quote);
}

equal_list_ba<FieldNames, Row, quote_type0>
Row::equal_list(const char* d, const char* e) const
{
	return equal_list_ba<FieldNames, Row, quote_type0>(
			parent().names(), *this, d, e, quote);
}

template <class Manip>
equal_list_ba<FieldNames, Row, Manip>
Row::equal_list(const char* d, const char* e, Manip m) const 
{
	return equal_list_ba<FieldNames, Row, Manip>(
			parent().names(), *this, d, e, m);
}

} // end namespace mysqlpp

Deleted lib/row.h.
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































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file row.h
/// \brief Declares the classes for holding row data from a result set.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_ROW_H
#define MYSQLPP_ROW_H

#include "coldata.h"
#include "exceptions.h"
#include "noexceptions.h"
#include "resiter.h"
#include "vallist.h"

#include <vector>
#include <string>

#include <string.h>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class FieldNames;
class MYSQLPP_EXPORT ResUse;
#endif

/// \brief Manages rows from a result set.
class MYSQLPP_EXPORT Row :
		public const_subscript_container<Row, ColData, const ColData>,
		public OptionalExceptions
{
public:
	/// \brief Default constructor
	Row() :
	res_(0),
	initialized_(false)
	{
	}
	
	/// \brief Create a row object
	///
	/// \param d MySQL C API row data
	/// \param r result set that the row comes from
	/// \param jj length of each item in d
	/// \param te if true, throw exceptions on errors
	Row(const MYSQL_ROW& d, const ResUse* r,
			unsigned long* jj, bool te = true);

	/// \brief Destroy object
	~Row();

	/// \brief Get a reference to our parent class.
	const ResUse& parent() const
	{
		return *res_;
	}

	/// \brief Get the number of fields in the row.
	size_type size() const;

	/// \brief Get the value of a field given its name.
	///
	/// If the field does not exist in this row, we throw a BadFieldName
	/// exception.
	///
	/// For this operator to work, the Result or ResUse object that
	/// created this object must still exist.  In other words, you
	/// cannot re-use or destroy the result object until you are done
	/// retrieving data from this row object.
	///
	/// Note that we return the
	/// \link mysqlpp::ColData_Tmpl ColData \endlink object by value.
	/// The purpose of ColData is to make it easy to convert the string
	/// data returned by the MySQL server to some more appropriate type,
	/// so you're almost certain to use this operator in a construct
	/// like this:
	///
	/// \code
	///  string s = row["myfield"];
	/// \endcode
	///
	/// That accesses myfield within the row, returns a temporary
	/// ColData object, which is then automatically converted to a
	/// \c std::string and copied into \c s.  That works fine, but
	/// beware of this similar but incorrect construct:
	///
	/// \code
	///  const char* pc = row["myfield"];
	/// \endcode
	///
	/// This one line of code does what you expect, but \c pc is then a
	/// dangling pointer: it points to memory owned by the temporary
	/// ColData object, which will have been destroyed by the time you
	/// get around to actually \e using the pointer.
	///
	/// This function is rather inefficient.  If that is a concern for
	/// you, use at(), operator[](size_type) or the SSQLS mechanism'
	/// instead.
	const ColData operator [](const char* field) const;

	/// \brief Get the value of a field given its index.
	///
	/// This function is just syntactic sugar, wrapping the at() method.
	/// The at() method is the only way to get at the first field in a
	/// result set by index, as \c row[0] is ambiguous: it could call
	/// either \c operator[] overload.
	///
	/// \sa at() for the full documentation for this operator, and
	/// operator[](const char*) for further caveats about using this
	/// operator.
	const ColData operator [](size_type i) const
	{
		return at(i);
	}

	/// \brief Get the value of a field given its index.
	///
	/// If the index value is bad, the underlying std::vector is
	/// supposed to throw an exception, according to the Standard.
	///
	/// For this function to work, the Result or ResUse object that
	/// created this object must still exist.  In other words, you
	/// cannot re-use or destroy the result object until you are done
	/// retrieving data from this row object.
	///
	/// See operator[](const char*) for more caveats.
	const ColData at(size_type i) const;

	/// \brief Return the value of a field as a C string given its
	/// index, in raw form.
	///
	/// This is the same thing as operator[], except that the data isn't
	/// converted to a ColData object first.  Also, this method does not
	/// check for out-of-bounds array indices.
	const char* raw_data(int i) const
	{
		return data_[i].data();
	}

	/// \brief Return the size of a field's raw data given its index.
	std::string::size_type raw_size(int i) const
	{
		return data_[i].length();
	}

	/// \brief Return the value of a field as a C++ string given its
	/// index, in raw form.
	///
	/// This is the same thing as operator[], except that the data isn't
	/// converted to a ColData object first.
	const std::string& raw_string(int i) const
	{
		return data_.at(i);
	}

	/// \brief Returns true if there is data in the row.
	operator bool() const
	{
		return data_.size();
	}

	/// \brief Get a list of the values in this row
	///
	/// When inserted into a C++ stream, the delimiter 'd' will be used
	/// between the items, and the quoting and escaping rules will be
	/// set by the manipulator 'm' you choose.
	///
	/// \param d delimiter to use between values
	/// \param m manipulator to use when inserting values into a stream
	template <class Manip>
	value_list_ba<Row, Manip> value_list(const char* d = ",",
			Manip m = quote) const
	{
		return value_list_ba<Row, Manip>(*this, d, m);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// \param d delimiter to use between values
	/// \param vb for each true item in this list, add that value to the
	/// returned list; ignore the others
	/// \param m manipulator to use when inserting values into a stream
	template <class Manip>
	value_list_b<Row, Manip> value_list(const char *d,
			const std::vector<bool>& vb, Manip m = quote) const
	{
		return value_list_b<Row, Manip>(*this, vb, d, m);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// \param vb for each true item in this list, add that value to the
	/// returned list; ignore the others
	///
	/// Items will be quoted and escaped when inserted into a C++ stream,
	/// and a comma will be used as a delimiter between the items.
	value_list_b<Row, quote_type0> value_list(
			const std::vector<bool> &vb) const
	{
		return value_list_b<Row, quote_type0>(*this, vb, ",", quote);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// For each true parameter, the value in that position within the
	/// row is added to the returned list.  When the list is inserted
	/// into a C++ stream, the delimiter 'd' will be placed between the
	/// items, and the manipulator 'm' used before each item.
	template <class Manip>
	value_list_b<Row, Manip> value_list(const char *d, Manip m,
			bool t0, bool t1 = false, bool t2 = false, bool t3 = false,
			bool t4 = false, bool t5 = false, bool t6 = false,
			bool t7 = false, bool t8 = false, bool t9 = false,
			bool ta = false, bool tb = false, bool tc = false) const
	{
		std::vector<bool> vb;
		create_vector(size(), vb, t0, t1, t2, t3, t4, t5, t6,
				t7, t8, t9, ta, tb, tc);
		return value_list_b<Row, Manip>(*this, vb, d, m);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// For each true parameter, the value in that position within the
	/// row is added to the returned list.  When the list is inserted
	/// into a C++ stream, the delimiter 'd' will be placed between the
	/// items, and items will be quoted and escaped.
	value_list_b <Row, quote_type0>
	value_list(const char *d, bool t0, bool t1 = false, bool t2 = false,
			bool t3 = false, bool t4 = false, bool t5 = false,
			bool t6 = false, bool t7 = false, bool t8 = false,
			bool t9 = false, bool ta = false, bool tb = false,
			bool tc = false) const
	{
		std::vector<bool> vb;
		create_vector(size(), vb, t0, t1, t2, t3, t4, t5, t6,
				t7, t8, t9, ta, tb, tc);
		return value_list_b<Row, quote_type0>(*this, vb, d, quote);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// For each true parameter, the value in that position within the
	/// row is added to the returned list.  When the list is inserted
	/// into a C++ stream, the a comma will be placed between the items,
	/// as a delimiter, and items will be quoted and escaped.
	value_list_b<Row, quote_type0> value_list(bool t0,
			bool t1 = false, bool t2 = false, bool t3 = false,
			bool t4 = false, bool t5 = false, bool t6 = false,
			bool t7 = false, bool t8 = false, bool t9 = false,
			bool ta = false, bool tb = false, bool tc = false) const
	{
		std::vector<bool> vb;
		create_vector(size(), vb, t0, t1, t2, t3, t4, t5, t6,
				t7, t8, t9, ta, tb, tc);
		return value_list_b<Row, quote_type0>(*this, vb, ",", quote);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// The 's' parameters name the fields that will be added to the
	/// returned list.  When inserted into a C++ stream, the delimiter
	/// 'd' will be placed between the items, and the manipulator 'm'
	/// will be inserted before each item.
	template <class Manip>
	value_list_b<Row, Manip> value_list(const char *d, Manip m,
			std::string s0, std::string s1 = "", std::string s2 = "",
			std::string s3 = "", std::string s4 = "",
			std::string s5 = "", std::string s6 = "",
			std::string s7 = "", std::string s8 = "",
			std::string s9 = "", std::string sa = "",
			std::string sb = "", std::string sc = "") const
	{
		std::vector<bool> vb;
		create_vector(*this, vb, s0, s1, s2, s3, s4, s5, s6, s7, s8,
				s9, sa, sb, sc);
		return value_list_b<Row, Manip>(*this, vb, d, m);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// The 's' parameters name the fields that will be added to the
	/// returned list.  When inserted into a C++ stream, the delimiter
	/// 'd' will be placed between the items, and items will be quoted
	/// and escaped.
	value_list_b<Row, quote_type0> value_list(
			const char *d,
			std::string s0, std::string s1 = "", std::string s2 = "",
			std::string s3 = "", std::string s4 = "",
			std::string s5 = "", std::string s6 = "",
			std::string s7 = "", std::string s8 = "",
			std::string s9 = "", std::string sa = "",
			std::string sb = "", std::string sc = "") const
	{
		std::vector<bool> vb;
		create_vector(*this, vb, s0, s1, s2, s3, s4, s5, s6, s7, s8,
				s9, sa, sb, sc);
		return value_list_b<Row, quote_type0>(*this, vb, d, quote);
	}
	
	/// \brief Get a list of the values in this row
	///
	/// The 's' parameters name the fields that will be added to the
	/// returned list.  When inserted into a C++ stream, a comma will be
	/// placed between the items as a delimiter, and items will be
	/// quoted and escaped.
	value_list_b<Row, quote_type0> value_list(
			std::string s0,
			std::string s1 = "", std::string s2 = "",
			std::string s3 = "", std::string s4 = "",
			std::string s5 = "", std::string s6 = "",
			std::string s7 = "", std::string s8 = "",
			std::string s9 = "", std::string sa = "",
			std::string sb = "", std::string sc = "") const
	{
		std::vector<bool> vb;
		create_vector(*this, vb, s0, s1, s2, s3, s4, s5, s6, s7, s8,
				s9, sa, sb, sc);
		return value_list_b<Row, quote_type0>(*this, vb, ",", quote);
	}

	/// \brief Get a list of the field names in this row
	///
	/// When inserted into a C++ stream, the delimiter 'd' will be used
	/// between the items, and no manipulator will be used on the items.
	value_list_ba<FieldNames, do_nothing_type0>
			field_list(const char* d = ",") const;

	/// \brief Get a list of the field names in this row
	///
	/// \param d delimiter to place between the items when the list is
	/// inserted into a C++ stream
	/// \param m manipulator to use before each item when the list is
	/// inserted into a C++ stream
	template <class Manip>
	value_list_ba<FieldNames, Manip> field_list(const char* d,
			Manip m) const;

	/// \brief Get a list of the field names in this row
	///
	/// \param d delimiter to place between the items when the list is
	/// inserted into a C++ stream
	/// \param m manipulator to use before each item when the list is
	/// inserted into a C++ stream
	/// \param vb for each true item in this list, add that field name
	/// to the returned list; ignore the others
	template <class Manip>
	value_list_b<FieldNames, Manip> field_list(const char* d, Manip m,
			const std::vector<bool>& vb) const;

	/// \brief Get a list of the field names in this row
	///
	/// \param d delimiter to place between the items when the list is
	/// inserted into a C++ stream
	/// \param vb for each true item in this list, add that field name
	/// to the returned list; ignore the others
	///
	/// Field names will be quoted and escaped when inserted into a C++
	/// stream.
	value_list_b<FieldNames, quote_type0> field_list(
			const char* d, const std::vector<bool>& vb) const;

	/// \brief Get a list of the field names in this row
	///
	/// \param vb for each true item in this list, add that field name
	/// to the returned list; ignore the others
	///
	/// Field names will be quoted and escaped when inserted into a C++
	/// stream, and a comma will be placed between them as a delimiter.
	value_list_b<FieldNames, quote_type0> field_list(
			const std::vector<bool>& vb) const;

	/// \brief Get a list of the field names in this row
	///
	/// For each true parameter, the field name in that position within
	/// the row is added to the returned list.  When the list is
	/// inserted into a C++ stream, the delimiter 'd' will be placed
	/// between the items as a delimiter, and the manipulator 'm' used
	/// before each item.
	template <class Manip>
	value_list_b<FieldNames, Manip> field_list(const char *d, Manip m,
			bool t0,
			bool t1 = false, bool t2 = false, bool t3 = false,
			bool t4 = false, bool t5 = false, bool t6 = false,
			bool t7 = false, bool t8 = false, bool t9 = false,
			bool ta = false, bool tb = false, bool tc = false) const;

	/// \brief Get a list of the field names in this row
	///
	/// For each true parameter, the field name in that position within
	/// the row is added to the returned list.  When the list is
	/// inserted into a C++ stream, the delimiter 'd' will be placed
	/// between the items as a delimiter, and the items will be quoted
	/// and escaped.
	value_list_b<FieldNames, quote_type0> field_list(
			const char *d, bool t0,
			bool t1 = false, bool t2 = false, bool t3 = false,
			bool t4 = false, bool t5 = false, bool t6 = false,
			bool t7 = false, bool t8 = false, bool t9 = false,
			bool ta = false, bool tb = false, bool tc = false) const;

	/// \brief Get a list of the field names in this row
	///
	/// For each true parameter, the field name in that position within
	/// the row is added to the returned list.  When the list is
	/// inserted into a C++ stream, a comma will be placed between the
	/// items as a delimiter, and the items will be quoted and escaped.
	value_list_b<FieldNames, quote_type0> field_list(
			bool t0,
			bool t1 = false, bool t2 = false, bool t3 = false,
			bool t4 = false, bool t5 = false, bool t6 = false,
			bool t7 = false, bool t8 = false, bool t9 = false,
			bool ta = false, bool tb = false, bool tc = false) const;

	/// \brief Get an "equal list" of the fields and values in this row
	///
	/// When inserted into a C++ stream, the delimiter 'd' will be used
	/// between the items, " = " is the relationship operator, and items
	/// will be quoted and escaped.
	equal_list_ba<FieldNames, Row, quote_type0>
			equal_list(const char* d = ",", const char* e = " = ") const;

	/// \brief Get an "equal list" of the fields and values in this row
	///
	/// This method's parameters govern how the returned list will
	/// behave when you insert it into a C++ stream:
	///
	/// \param d delimiter to use between items
	/// \param e the operator to use between elements
	/// \param m the manipulator to use for each element
	///
	/// For example, if d is ",", e is " = ", and m is the quote
	/// manipulator, then the field and value lists (a, b) (c, d'e)
	/// will yield an equal list that gives the following when inserted
	/// into a C++ stream:
	///
	/// \code
	///   'a' = 'c', 'b' = 'd''e'
	/// \endcode
	///
	/// Notice how the single quote was 'escaped' in the SQL way to
	/// avoid a syntax error.
	template <class Manip>
	equal_list_ba<FieldNames, Row, Manip> equal_list(const char* d,
			const char* e, Manip m) const;

private:
	std::vector<std::string> data_;
	std::vector<bool> is_nulls_;
	const ResUse* res_;
	bool initialized_;
};

} // end namespace mysqlpp

#endif
Deleted lib/sql_string.cpp.
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


















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 sql_string.cpp - Implements the SQLString template.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "sql_string.h"

#include <iomanip>
#include <sstream>

using namespace std;

namespace mysqlpp {

SQLString::SQLString() :
is_string(false),
dont_escape(false),
processed(false)
{
}

SQLString::SQLString(const string& str) :
string(str),
is_string(true),
dont_escape(false),
processed(false)
{
}

SQLString::SQLString(const char* str) : 
string(str),
is_string(true),
dont_escape(false),
processed(false)
{
}

SQLString::SQLString(const char* str, size_t len) : 
string(str, len),
is_string(true),
dont_escape(false),
processed(false)
{
}

SQLString::SQLString(char i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << static_cast<short int>(i);
	assign(outs.str());
}

SQLString::SQLString(unsigned char i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << static_cast<unsigned short int>(i);
	assign(outs.str());
}

SQLString::SQLString(short int i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << i;
	assign(outs.str());
}

SQLString::SQLString(unsigned short int i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << i;
	assign(outs.str());
}

SQLString::SQLString(int i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << i;
	assign(outs.str());
}

SQLString::SQLString(unsigned int i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << i;
	assign(outs.str());
}

SQLString::SQLString(longlong i) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs << i;
	assign(outs.str());
}

SQLString::SQLString(ulonglong i) :
is_string(false),
dont_escape(false),
processed(false) 
{
	ostringstream outs;
	outs << i;
	assign(outs.str());
}

SQLString::SQLString(float f) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs.precision(7);	// max digits in IEEE 754 single-prec float
	outs << f;
	assign(outs.str());
}

SQLString::SQLString(double f) :
is_string(false),
dont_escape(false),
processed(false)
{
	ostringstream outs;
	outs.precision(16);	// max digits in IEEE 754 double-prec float
	outs << f;
	assign(outs.str());
}

SQLString::SQLString(const null_type& i) :
string("NULL"),
is_string(false),
dont_escape(false),
processed(false)
{
}

} // end namespace mysqlpp

Deleted lib/sql_string.h.
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















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file sql_string.h
/// \brief Declares an \c std::string derivative that adds some things
/// needed within the library.
///
/// This class adds some flags needed by other parts of MySQL++, and it
/// adds conversion functions from any primitive type.  This helps in
/// inserting these primitive types into the database, because we need
/// everything in string form to build SQL queries.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_SQL_STRING_H
#define MYSQLPP_SQL_STRING_H

#include "common.h"
#include "null.h"

#include <stdio.h>
#include <string>

namespace mysqlpp {

/// \brief A specialized \c std::string that will convert from any
/// valid MySQL type.

class MYSQLPP_EXPORT SQLString : public std::string {
public:
	/// \brief If true, the object's string data is a copy of another
	/// string.  Otherwise, it's the string form of an integral type.
	bool is_string;

	/// \brief If true, the string data doesn't need to be SQL-escaped
	/// when building a query.
	bool dont_escape;

	/// \brief If true, one of the MySQL++ manipulators has processed
	/// the string data.
	///
	/// "Processing" is escaping special SQL characters, and/or adding
	/// quotes.  See the documentation for manip.h for details.
	///
	/// This flag is used by the template query mechanism, to prevent a
	/// string from being re-escaped or re-quoted each time that query
	/// is reused.  The flag is reset by operator=, to force the new
	/// parameter value to be re-processed.
	bool processed;

	/// \brief Default constructor; empty string
	SQLString();

	/// \brief Create object as a copy of a C++ string
	SQLString(const std::string& str);

	/// \brief Create object as a copy of a C string
	SQLString(const char* str);

	/// \brief Create object as a copy of a known-length string of
	/// characters.
	SQLString(const char* str, size_t len);

	/// \brief Create object as the string form of a \c char value
	SQLString(char i);

	/// \brief Create object as the string form of an \c unsigned
	/// \c char value
	SQLString(unsigned char i);

	/// \brief Create object as the string form of a \c short \c int
	/// value
	SQLString(short int i);

	/// \brief Create object as the string form of an \c unsigned
	/// \c short \c int value
	SQLString(unsigned short int i);

	/// \brief Create object as the string form of an \c int value
	SQLString(int i);

	/// \brief Create object as the string form of an \c unsigned
	/// \c int value
	SQLString(unsigned int i);

	/// \brief Create object as the string form of a \c longlong
	/// value
	SQLString(longlong i);

	/// \brief Create object as the string form of an \c unsigned
	/// \c longlong value
	SQLString(ulonglong i);

	/// \brief Create object as the string form of a \c float
	/// value
	SQLString(float i);

	/// \brief Create object as the string form of a \c double
	/// value
	SQLString(double i);

	/// \brief Create object representing NULL
	SQLString(const null_type& i);

	/// \brief Copy a C string into this object
	SQLString& operator =(const char* str)
	{
		std::string::operator =(str);
		processed = false;
		return *this;
	}

	/// \brief Copy a C++ \c string into this object
	SQLString& operator =(const std::string& str)
	{
		std::string::operator =(str);
		processed = false;
		return *this;
	}
};

} // end namespace mysqlpp

#endif
Deleted lib/sql_types.h.
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





















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file sql_types.h
/// \brief Declares the closest C++ equivalent of each MySQL column type

/***********************************************************************
 Copyright (c) 2006 by Educational Technology Resources, Inc.  Others
 may also hold copyrights on code in this file.  See the CREDITS file in
 the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#if !defined(MYSQLPP_SQL_TYPES_H)
#define MYSQLPP_SQL_TYPES_H

#include "common.h"

#include <string>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

// Nearest C++ equivalents of MySQL data types.  These are only the "NOT
// NULL" variants.  Wrap these types in MySQL++'s Null<> template to get
// NULL-able types.
typedef signed char		sql_tinyint;
typedef unsigned char	sql_tinyint_unsigned;
typedef short			sql_smallint;
typedef unsigned short	sql_smallint_unsigned;
typedef int				sql_int;
typedef unsigned int 	sql_int_unsigned;
typedef int				sql_mediumint;
typedef unsigned int 	sql_mediumint_unsigned;
typedef longlong		sql_bigint;
typedef ulonglong		sql_bigint_unsigned;

typedef float			sql_float;
typedef double			sql_double;
typedef double			sql_decimal;

typedef std::string		sql_enum;

typedef ColData			sql_blob;
typedef ColData			sql_tinyblob;
typedef ColData			sql_mediumblob;
typedef ColData			sql_longblob;

typedef std::string		sql_char;
typedef std::string		sql_varchar;

#ifdef MYSQLPP_DATETIME_H
    // MySQL++ date and time types are defined, so make aliases for
    // them matching the style of the above types.
    typedef Date		sql_date;
    typedef Time		sql_time;
    typedef Time		sql_timestamp;
    typedef DateTime	sql_datetime;
#endif
#ifdef MYSQLPP_MYSET_H
    // Ditto for MySQL++'s SQL set type
    typedef Set<>		sql_set;
#endif

#endif // !defined(DOXYGEN_IGNORE)

} // end namespace mysqlpp

#endif // !defined(MYSQLPP_SQL_TYPES_H)

Deleted lib/stream2string.h.
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
























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file stream2string.h
/// \brief Declares an adapter that converts something that can be
/// inserted into a C++ stream into a string type.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_STREAM2STRING_H
#define MYSQLPP_STREAM2STRING_H

#include <sstream>

namespace mysqlpp {

/// \brief Converts a stream-able object to any type that can be
/// initialized from an \c std::string.
///
/// This adapter takes any object that has an \c out_stream() member
/// function and converts it to a string type.  An example of such a
/// type within the library is mysqlpp::Date.

template <class Strng, class T>
Strng stream2string(const T& object)
{
	std::ostringstream str;
	object.out_stream(str);
	str << std::ends;
	Strng s = str.str();
	return s;
}

} // end namespace mysqlpp

#endif

Deleted lib/string_util.cpp.
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

















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 string_util.cpp - Implements utility functions for manipulating
	C++ strings.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "string_util.h"

namespace mysqlpp {

void strip(std::string& s)
{
	size_t i, j = s.size() - 1;
	if (!s.size()) {
		return;
	}
	for (i = 0; s[i] == ' '; i++) ;
	if (i) {
		s.erase(0, i);
	}
	j = s.size();
	if (!j) {
		return;
	}
	j--;
	for (i = j; i && s[i] == ' '; i--) ;
	if (i != j) {
		s.erase(i + 1, static_cast<size_t> (-1));
	}
}

void escape_string(std::string & s)
{
	if (!s.size()) {
		return;
	}

	for (unsigned int i = 0; i < s.size(); i++) {
		switch (s[i]) {
			case '\0':		// Must be escaped for "mysql"
				s[i] = '\\';
				s.insert(i, "0", 1);
				i++;
				break;
			case '\n':		// Must be escaped for logs
				s[i] = '\\';
				s.insert(i, "n", 1);
				i++;
				break;
			case '\r':
				s[i] = '\\';
				s.insert(i, "r", 1);
				i++;
				break;
			case '\\':
				s[i] = '\\';
				s.insert(i, "\\", 1);
				i++;
				break;
			case '\"':
				s[i] = '\\';
				s.insert(i, "\"", 1);
				i++;
				break;
			case '\'':		// Better safe than sorry
				s[i] = '\\';
				s.insert(i, "\'", 1);
				i++;
				break;
			case '\032':	// This gives problems on Win32
				s[i] = '\\';
				s.insert(i, "Z", 1);
				i++;
				break;
			default:
				break;
		}
	}
}


void
str_to_upr(std::string& s)
{
	for (std::string::size_type i = 0; i < s.length(); ++i) {
		s[i] = toupper(s[i]);
	}
}


void
str_to_lwr(std::string& s)
{
	for (std::string::size_type i = 0; i < s.length(); ++i) {
		s[i] = tolower(s[i]);
	}
}


void
strip_all_blanks(std::string& s)
{
	for (std::string::size_type i = 0; i < s.length(); ++i) {
		if (s[i] == ' ') {
			s.erase(i, 1);
			--i;
		}
	}
}


void
strip_all_non_num(std::string& s)
{
	for (std::string::size_type i = 0; i < s.length(); ++i) {
		if (!isdigit(s[i])) {
			s.erase(i, 1);
			--i;
		}
	}
}

} // end namespace mysqlpp

Deleted lib/string_util.h.
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





























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file string_util.h
/// \brief Declares string-handling utility functions used within
/// the library.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_STRING_UTIL_H
#define MYSQLPP_STRING_UTIL_H

#include "common.h"

#include <ctype.h>

#include <string>

namespace mysqlpp {

/// \brief Strips blanks at left and right ends
MYSQLPP_EXPORT extern void strip(std::string& s);

/// \brief C++ equivalent of mysql_escape_string()
MYSQLPP_EXPORT extern void escape_string(std::string& s);

/// \brief Changes case of string to upper
MYSQLPP_EXPORT extern void str_to_upr(std::string& s);

/// \brief Changes case of string to lower
MYSQLPP_EXPORT extern void str_to_lwr(std::string& s);

/// \brief Removes all blanks
MYSQLPP_EXPORT extern void strip_all_blanks(std::string& s);

/// \brief Removes all non-numerics
MYSQLPP_EXPORT extern void strip_all_non_num(std::string& s);

} // end namespace mysqlpp

#endif

Deleted lib/tiny_int.h.
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















































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file tiny_int.h
/// \brief Declares class for holding a SQL tiny_int

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_TINY_INT_H
#define MYSQLPP_TINY_INT_H

namespace mysqlpp {

/// \brief Class for holding an SQL \c tiny_int object.
///
/// This is required because the closest C++ type, \c char, doesn't
/// have all the right semantics.  For one, inserting a \c char into a
/// stream won't give you a number.
///
/// Several of the functions below accept a \c short \c int argument,
/// but internally we store the data as a \c char. Beware of integer
/// overflows!

class MYSQLPP_EXPORT tiny_int
{
public:
	/// \brief Default constructor
	///
	/// Value is uninitialized
	tiny_int() { }
	
	/// \brief Create object from any integral type that can be
	/// converted to a \c short \c int.
	tiny_int(short int v) :
	value_(char(v))
	{
	}
	
	/// \brief Return value as a \c short \c int.
	operator short int() const
	{
		return static_cast<short int>(value_);
	}

	/// \brief Assign a \c short \c int to the object.
	tiny_int& operator =(short int v)
	{
		value_ = char(v);
		return *this;
	}

	/// \brief Add another value to this object
	tiny_int& operator +=(short int v)
	{
		value_ += char(v);
		return *this;
	}

	/// \brief Subtract another value to this object
	tiny_int& operator -=(short int v)
	{
		value_ -= char(v);
		return *this;
	}

	/// \brief Multiply this value by another object
	tiny_int& operator *=(short int v)
	{
		value_ *= char(v);
		return *this;
	}

	/// \brief Divide this value by another object
	tiny_int& operator /=(short int v)
	{
		value_ /= char(v);
		return *this;
	}

	/// \brief Divide this value by another object and store the
	/// remainder
	tiny_int& operator %=(short int v)
	{
		value_ %= char(v);
		return *this;
	}

	/// \brief Bitwise AND this value by another value
	tiny_int& operator &=(short int v)
	{
		value_ &= char(v);
		return *this;
	}

	/// \brief Bitwise OR this value by another value
	tiny_int& operator |=(short int v)
	{
		value_ |= char(v);
		return *this;
	}

	/// \brief Bitwise XOR this value by another value
	tiny_int& operator ^=(short int v)
	{
		value_ ^= char(v);
		return *this;
	}

	/// \brief Shift this value left by \c v positions
	tiny_int& operator <<=(short int v)
	{
		value_ <<= char(v);
		return *this;
	}

	/// \brief Shift this value right by \c v positions
	tiny_int& operator >>=(short int v)
	{
		value_ >>= char(v);
		return *this;
	}

	/// \brief Add one to this value and return that value
	tiny_int& operator ++()
	{
		value_++;
		return *this;
	}

	/// \brief Subtract one from this value and return that value
	tiny_int& operator --()
	{
		value_--;
		return *this;
	}

	/// \brief Add one to this value and return the previous value
	tiny_int operator ++(int)
	{
		tiny_int tmp = value_;
		value_++;
		return tmp;
	}

	/// \brief Subtract one from this value and return the previous
	/// value
	tiny_int operator --(int)
	{
		tiny_int tmp = value_;
		value_--;
		return tmp;
	}

	/// \brief Return this value minus \c i
	tiny_int operator -(const tiny_int& i) const
	{
		return value_ - i;
	}
	
	/// \brief Return this value plus \c i
	tiny_int operator +(const tiny_int& i) const
	{
		return value_ + i;
	}
	
	/// \brief Return this value multiplied by \c i
	tiny_int operator *(const tiny_int& i) const
	{
		return value_ * i;
	}
	
	/// \brief Return this value divided by \c i
	tiny_int operator /(const tiny_int& i) const
	{
		return value_ / i;
	}
	
	/// \brief Return the modulus of this value divided by \c i
	tiny_int operator %(const tiny_int& i) const
	{
		return value_ % i;
	}
	
	/// \brief Return this value bitwise OR'd by \c i
	tiny_int operator |(const tiny_int& i) const
	{
		return value_ | i;
	}
	
	/// \brief Return this value bitwise AND'd by \c i
	tiny_int operator &(const tiny_int& i) const
	{
		return value_ & i;
	}
	
	/// \brief Return this value bitwise XOR'd by \c i
	tiny_int operator ^(const tiny_int& i) const
	{
		return value_ ^ i;
	}
	
	/// \brief Return this value bitwise shifted left by \c i
	tiny_int operator <<(const tiny_int& i) const
	{
		return value_ << i;
	}
	
	/// \brief Return this value bitwise shifted right by \c i
	tiny_int operator >>(const tiny_int& i) const
	{
		return value_ >> i;
	}

private:
	char value_;
};

} // end namespace mysqlpp

#endif
Deleted lib/transaction.cpp.
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

































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 transaction.cpp - Implements the Transaction class.

 Copyright (c) 2006 by Educational Technology Resources, Inc.  Others
 may also hold copyrights on code in this file.  See the CREDITS file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "common.h"

#include "transaction.h"

#include "connection.h"
#include "query.h"

using namespace std;
using namespace mysqlpp;


//// ctor //////////////////////////////////////////////////////////////

Transaction::Transaction(Connection& conn, bool consistent) :
conn_(conn),
finished_(true)		// don't bother rolling it back if ctor fails
{
	// Begin the transaction set
	Query q(conn_.query());
	q << "START TRANSACTION";
	if (consistent) {
		q << " WITH CONSISTENT SNAPSHOT";
	}
	q.execute();

	// Setup succeeded, so mark our transaction as not-finished.
	finished_ = false;
}


//// dtor //////////////////////////////////////////////////////////////

Transaction::~Transaction()
{
	if (!finished_) {
		try {
			rollback();
		}
		catch (...) {
			// eat all exceptions
		}
	}
}


//// commit ////////////////////////////////////////////////////////////

void
Transaction::commit()
{
	Query q(conn_.query());
	q << "COMMIT";
	q.execute();

	finished_ = true;
}


//// rollback //////////////////////////////////////////////////////////

void
Transaction::rollback()
{
	Query q(conn_.query());
	q << "ROLLBACK";
	q.execute();

	finished_ = true;
}


Deleted lib/transaction.h.
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



























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file transaction.h
/// \brief Declares the Transaction class.
///
/// This object works with the Connection class to automate the use of
/// MySQL transactions.  It allows you to express these transactions
/// directly in C++ code instead of sending the raw SQL commands.

/***********************************************************************
 Copyright (c) 2006 by Educational Technology Resources, Inc.  Others
 may also hold copyrights on code in this file.  See the CREDITS file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#if !defined(MYSQLPP_TRANSACTION_H)
#define MYSQLPP_TRANSACTION_H

#include "common.h"

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT Connection;
#endif

/// \brief Helper object for creating exception-safe SQL transactions.

class MYSQLPP_EXPORT Transaction
{
public:
	/// \brief Constructor
	///
	/// \param conn The connection we use to manage the transaction set
	/// \param consistent Whether to use "consistent snapshots" during
	/// the transaction. See the documentation for "START TRANSACTION"
	/// in the MySQL manual for more on this.
	Transaction(Connection& conn, bool consistent = false);

	/// \brief Destructor
	///
	/// If the transaction has not been committed or rolled back by the
	/// time the destructor is called, it is rolled back.  This is the
	/// right thing because one way this can happen is if the object is
	/// being destroyed as the stack is unwound to handle an exception.
	/// In that instance, you certainly want to roll back the
	/// transaction.
	~Transaction();

	/// \brief Commits the transaction
	///
	/// This commits all updates to the database using the connection
	/// we were created with since this object was created.  This is a
	/// no-op if the table isn't stored using a transaction-aware
	/// storage engine.  See CREATE TABLE in the MySQL manual for
	/// details.
	void commit();

	/// \brief Rolls back the transaction
	///
	/// This abandons all SQL statements made on the connection since
	/// this object was created.  This only works on tables stored using
	/// a transaction-aware storage engine.  See CREATE TABLE in the
	/// MySQL manual for details.
	void rollback();

private:
	Connection& conn_;	///! Connection to send queries through
	bool finished_;		///! True when we commit or roll back xaction
};

} // end namespace mysqlpp

#endif // !defined(MYSQLPP_TRANSACTION_H)

Deleted lib/type_info.cpp.
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
































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 type_info.cpp - Implements the mysql_type_info class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "common.h"
#include "type_info.h"

#include "datetime.h"
#include "myset.h"
#include "sql_types.h"

#include <mysql.h>

#include <string>

using namespace std;

namespace mysqlpp {

// The first half of this array roughly parallels enum_field_types
// in mysql/mysql_com.h.  It is a lookup table used by the type() method
// below when translating from SQL type information to the closest
// C++ equivalent.
//
// The second half of the list parallels the first, to handle null-able
// versions of the types in the first half.  This is required because
// SQL's 'null' concept does not map neatly into the C++ type system, so
// null-able versions of these types have to have a different C++ type,
// implemented using the Null template.  See null.h for further details.
//
// Types marked true (the "default" field) are added to a lookup map in
// the mysql_type_info_lookup class in order to provide reverse lookup
// of C++ types to SQL types.  Put another way, if you take the subset
// of all items marked true, the typeid() of each item must be unique.
const mysql_type_info::sql_type_info mysql_type_info::types[62] = {
	sql_type_info("DECIMAL NOT NULL", typeid(sql_decimal), 0),
	sql_type_info("TINYINT NOT NULL", typeid(sql_tinyint), 1, true),
	sql_type_info("SMALLINT NOT NULL", typeid(sql_smallint), 2, true),
	sql_type_info("INT NOT NULL", typeid(sql_int), 3, true),
	sql_type_info("FLOAT NOT NULL", typeid(sql_float), 4, true),
	sql_type_info("DOUBLE NOT NULL", typeid(sql_double), 5, true),
	sql_type_info("NULL NOT NULL", typeid(void), 6),
	sql_type_info("TIMESTAMP NOT NULL", typeid(sql_timestamp), 7),
	sql_type_info("BIGINT NOT NULL", typeid(sql_bigint), 8, true),
	sql_type_info("MEDIUMINT NOT NULL", typeid(sql_mediumint), 9),
	sql_type_info("DATE NOT NULL", typeid(sql_date), 10, true),
	sql_type_info("TIME NOT NULL", typeid(sql_time), 11, true),
	sql_type_info("DATETIME NOT NULL", typeid(sql_datetime), 12, true),
	sql_type_info("ENUM NOT NULL", typeid(sql_enum), 13, true),
	sql_type_info("SET NOT NULL", typeid(sql_set), 14, true),
	sql_type_info("TINYBLOB NOT NULL", typeid(sql_tinyblob), 15),
	sql_type_info("MEDIUMBLOB NOT NULL", typeid(sql_mediumblob), 16),
	sql_type_info("LONGBLOB NOT NULL", typeid(sql_longblob), 17),
	sql_type_info("BLOB NOT NULL", typeid(sql_blob), 18),
	sql_type_info("VARCHAR NOT NULL", typeid(sql_varchar), 19, true),
	sql_type_info("CHAR NOT NULL", typeid(sql_char), 20),
	sql_type_info("CHAR NOT NULL", typeid(sql_char), 21),
	sql_type_info("TINYINT UNSIGNED NOT NULL", typeid(sql_tinyint_unsigned), 22, true),
	sql_type_info("SMALLINT UNSIGNED NOT NULL", typeid(sql_smallint_unsigned), 23, true),
	sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 24),
	sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 25),
	sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 26),
	sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 27),
	sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 28, true),
	sql_type_info("BIGINT UNSIGNED NOT NULL", typeid(sql_bigint_unsigned), 29, true),
	sql_type_info("MEDIUMINT UNSIGNED NOT NULL", typeid(sql_mediumint_unsigned), 30),

	sql_type_info("DECIMAL NULL", typeid(Null<sql_decimal>), 0),
	sql_type_info("TINYINT NULL", typeid(Null<sql_tinyint>), 1, true),
	sql_type_info("SMALLINT NULL", typeid(Null<sql_smallint>), 2, true),
	sql_type_info("INT NULL", typeid(Null<sql_int>), 3, true),
	sql_type_info("FLOAT NULL", typeid(Null<sql_float>), 4, true),
	sql_type_info("DOUBLE NULL", typeid(Null<sql_double>), 5, true),
	sql_type_info("NULL NULL", typeid(Null<void>), 6),
	sql_type_info("TIMESTAMP NULL", typeid(Null<sql_timestamp>), 7),
	sql_type_info("BIGINT NULL", typeid(Null<sql_bigint>), 8, true),
	sql_type_info("MEDIUMINT NULL", typeid(Null<sql_mediumint>), 9),
	sql_type_info("DATE NULL", typeid(Null<sql_date>), 10, true),
	sql_type_info("TIME NULL", typeid(Null<sql_time>), 11, true),
	sql_type_info("DATETIME NULL", typeid(Null<sql_datetime>), 12, true),
	sql_type_info("ENUM NULL", typeid(Null<sql_enum>), 13, true),
	sql_type_info("SET NULL", typeid(Null<sql_set>), 14, true),
	sql_type_info("TINYBLOB NULL", typeid(Null<sql_tinyblob>), 15),
	sql_type_info("MEDIUMBLOB NULL", typeid(Null<sql_mediumblob>), 16),
	sql_type_info("LONGBLOB NULL", typeid(Null<sql_longblob>), 17),
	sql_type_info("BLOB NULL", typeid(Null<sql_blob>), 18),
	sql_type_info("VARCHAR NULL", typeid(Null<sql_varchar>), 19, true),
	sql_type_info("CHAR NULL", typeid(Null<sql_char>), 20),
	sql_type_info("CHAR NULL", typeid(Null<sql_char>), 21),
	sql_type_info("TINYINT UNSIGNED NULL", typeid(Null<sql_tinyint_unsigned>), 22, true),
	sql_type_info("SMALLINT UNSIGNED NULL", typeid(Null<sql_smallint_unsigned>), 23, true),
	sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 24),
	sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 25),
	sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 26),
	sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 27),
	sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 28, true),
	sql_type_info("BIGINT UNSIGNED NULL", typeid(Null<sql_bigint_unsigned>), 29, true),
	sql_type_info("MEDIUMINT UNSIGNED NULL", typeid(Null<sql_mediumint_unsigned>), 30),
};

const mysql_type_info::sql_type_info_lookup
		mysql_type_info::lookups(mysql_type_info::types, 62);

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

mysql_ti_sql_type_info_lookup::mysql_ti_sql_type_info_lookup(
		const sql_type_info types[], const int size)
{
	for (int i = 0; i != size; i++) {
		if (types[i].default_) {
			map_[types[i].c_type_] = i;
		}
	}
}

#endif // !defined(DOXYGEN_IGNORE)

unsigned char mysql_type_info::type(enum_field_types t,
		bool _unsigned, bool _null) 
{
	if (_null) {
		if (_unsigned) {
			return unsigned_null_offset + t;
		}
		else {
			if (t < 200)
				return null_offset + t;
			else
				return null_offset + (t - 234);
		}
	}
	else {
		if (_unsigned) {
			return unsigned_offset + t;
		}
		else {
			if (t < 200)
				return offset + t;
			else
				return offset + (t - 234);
		}
	}
}

bool mysql_type_info::quote_q() const
{
	const type_info& ti = base_type().c_type();
	return ti == typeid(string) ||
			ti == typeid(sql_date) ||
			ti == typeid(sql_time) ||
			ti == typeid(sql_datetime) ||
			ti == typeid(sql_set);
}

bool mysql_type_info::escape_q() const
{
	const type_info& ti = c_type();
	return ti == typeid(string) ||
			ti == typeid(sql_enum) ||
			ti == typeid(sql_blob) ||
			ti == typeid(sql_tinyblob) ||
			ti == typeid(sql_mediumblob) ||
			ti == typeid(sql_longblob) ||
			ti == typeid(sql_char) ||
			ti == typeid(sql_varchar);
}

} // end namespace mysqlpp

Deleted lib/type_info.h.
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
















































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file type_info.h
/// \brief Declares classes that provide an interface between the SQL
/// and C++ type systems.
///
/// These classes are mostly used internal to the library.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_TYPE_INFO_H
#define MYSQLPP_TYPE_INFO_H

#include "common.h"

#include <map>
#include <typeinfo>

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Doxygen will not generate documentation for this section.

class MYSQLPP_EXPORT mysql_type_info;
class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup;

class MYSQLPP_EXPORT mysql_ti_sql_type_info
{
private:
	friend class mysql_type_info;
	friend class mysql_ti_sql_type_info_lookup;

	mysql_ti_sql_type_info& operator=(
			const mysql_ti_sql_type_info& b);
	
	// Not initting _base_type and _default because only mysql_type_info
	// can create them.  There *must* be only one copy of each.
	mysql_ti_sql_type_info() :
	sql_name_(0),
	c_type_(0),
	base_type_(0),
	default_(false) 
	{
	}
	
	mysql_ti_sql_type_info(const char* s,
			const std::type_info& t, const unsigned char bt = 0,
			const bool d = false) :
	sql_name_(s),
	c_type_(&t),
	base_type_(bt),
	default_(d)
	{
	}

	const char* sql_name_;
	const std::type_info* c_type_;
	const unsigned char base_type_;
	const bool default_;
};


struct type_info_cmp
{
	bool operator() (const std::type_info* lhs,
			const std::type_info* rhs) const
	{
		return lhs->before(*rhs) != 0;
	}
};

class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup
{
private:
	friend class mysql_type_info;

	typedef mysql_ti_sql_type_info sql_type_info;

	mysql_ti_sql_type_info_lookup(
			const sql_type_info types[], const int size);

	const unsigned char& operator [](
			const std::type_info& ti) const
	{
		return map_.find(&ti)->second;
	}

	std::map<const std::type_info*, unsigned char, type_info_cmp> map_;
};

#endif // !defined(DOXYGEN_IGNORE)


/// \brief Holds basic type information for ColData.
///
/// Class to hold basic type information for mysqlpp::ColData.
class MYSQLPP_EXPORT mysql_type_info
{
public:
	/// \brief Create object
	///
	/// \param n index into the internal type table
	///
	/// Because of the \c n parameter's definition, this constructor
	/// shouldn't be used outside the library.
	///
	/// The default is intended to try and crash a program using a
	/// default mysql_type_info object.  This is a very wrong thing
	/// to do.
	mysql_type_info(unsigned char n = static_cast<unsigned char>(-1)) :
	_length(0),
	_max_length(0),
	num_(n)
	{
	}

	/// \brief Create object from MySQL C API type info
	///
	/// \param t the MySQL C API type ID for this type
	/// \param _unsigned if true, this is the unsigned version of the type
	/// \param _null if true, this type can hold a SQL null
	mysql_type_info(enum_field_types t, bool _unsigned, bool _null) :
	_length(0),
	_max_length(0),
	num_(type(t, _unsigned, _null))
	{
	}

	/// \brief Create object from a MySQL C API field
	///
	/// \param f field from which we extract the type info
	mysql_type_info(const MYSQL_FIELD& f) :
	_length(f.length),
	_max_length(f.max_length),
	num_(type(f.type, (f.flags & UNSIGNED_FLAG) != 0,
			(f.flags & NOT_NULL_FLAG) == 0))
	{
	}

	/// \brief Create object as a copy of another
	mysql_type_info(const mysql_type_info& t) :
	_length(0),
	_max_length(0),
	num_(t.num_)
	{
	}

	/// \brief Create object from a C++ type_info object
	///
	/// This tries to map a C++ type to the closest MySQL data type.
	/// It is necessarily somewhat approximate.
	mysql_type_info(const std::type_info& t) :
	num_(lookups[t])
	{
	}

	/// \brief Assign a new internal type value
	///
	/// \param n an index into the internal MySQL++ type table
	///
	/// This function shouldn't be used outside the library.
	mysql_type_info& operator =(unsigned char n)
	{
		num_ = n;
		return *this;
	}

	/// \brief Assign another mysql_type_info object to this object
	mysql_type_info& operator =(const mysql_type_info& t)
	{
		num_ = t.num_;
		return *this;
	}

	/// \brief Assign a C++ type_info object to this object
	///
	/// This tries to map a C++ type to the closest MySQL data type.
	/// It is necessarily somewhat approximate.
	mysql_type_info& operator =(const std::type_info& t)
	{
		num_ = lookups[t];
		return *this;
	}

	/// \brief Returns an implementation-defined name of the C++ type.
	///
	/// Returns the name that would be returned by typeid().name() for
	/// the C++ type associated with the SQL type.
	const char* name() const { return deref().c_type_->name(); }

	/// \brief Returns the name of the SQL type.
	///
	/// Returns the SQL name for the type.
	const char* sql_name() const { return deref().sql_name_; }

	/// \brief Returns the type_info for the C++ type associated with
	/// the SQL type.
	///
	/// Returns the C++ type_info record corresponding to the SQL type.
	const std::type_info& c_type() const { return *deref().c_type_; }

	/// \brief Return length of data in this field
	///
	/// This only works if you initialized this object from a
	/// MYSQL_FIELD object.
	const unsigned int length() const { return _length; }

	/// \brief Return maximum length of data in this field
	///
	/// This only works if you initialized this object from a
	/// MYSQL_FIELD object.
	const unsigned int max_length() const { return _max_length; }

	/// \brief Returns the type_info for the C++ type inside of the
	/// mysqlpp::Null type.
	///
	/// Returns the type_info for the C++ type inside the mysqlpp::Null
	/// type.  If the type is not Null then this is the same as c_type().
	const mysql_type_info base_type() const
	{
		return mysql_type_info(deref().base_type_);
	}

	/// \brief Returns the ID of the SQL type.
	///
	/// Returns the ID number MySQL uses for this type.  Note: Do not
	/// depend on the value of this ID as it may change between MySQL
	/// versions.
	int id() const
	{
		return num_;
	}
	
	/// \brief Returns true if the SQL type is of a type that needs to
	/// be quoted.
	///
	/// \return true if the type needs to be quoted for syntactically
	/// correct SQL.
	bool quote_q() const;

	/// \brief Returns true if the SQL type is of a type that needs to
	/// be escaped.
	///
	/// \return true if the type needs to be escaped for syntactically
	/// correct SQL.
	bool escape_q() const;

	/// \brief Provides a way to compare two types for sorting.
	///
	/// Returns true if the SQL ID of this type is lower than that of
	/// another.  Used by mysqlpp::type_info_cmp when comparing types.
	bool before(mysql_type_info& b)
	{
		return num_ < b.num_;
	}

	/// \brief The internal constant we use for our string type.
	///
	/// We expose this because other parts of MySQL++ need to know
	/// what the string constant is at the moment.
	static const unsigned char string_type = 20;

	unsigned int _length;		///< field length, from MYSQL_FIELD
	unsigned int _max_length;	///< max data length, from MYSQL_FIELD

private:
	typedef mysql_ti_sql_type_info sql_type_info;
	typedef mysql_ti_sql_type_info_lookup sql_type_info_lookup;

	static const sql_type_info types[62];

	static const unsigned char offset = 0;
	static const unsigned char unsigned_offset = 21;
	static const unsigned char null_offset = 31;
	static const unsigned char unsigned_null_offset = 52;

	static const sql_type_info_lookup lookups;

	/// \brief Return an index into mysql_type_info::types array given
	/// MySQL type information.
	///
	/// This function is used in mapping from MySQL type information
	/// (a type enum, and flags indicating whether it is unsigned and
	/// whether it can be 'null') to the closest C++ types available
	/// within MySQL++.  Notice that nulls have to be handled specially:
	/// the SQL null concept doesn't map directly onto the C++ type
	/// system.  See null.h for details.
	///
	/// \param t MySQL C API type constant, from mysql_com.h
	/// \param _unsigned if true, indicates the unsigned variant of a
	/// MySQL type
	/// \param _null if true, indicates the variant of the MySQL type
	/// that can also hold an SQL 'null' instead of regular data.
	static unsigned char type(enum_field_types t,
			bool _unsigned, bool _null = false);

	const sql_type_info& deref() const
	{
		return types[num_];
	}

	unsigned char num_;
};

/// \brief Returns true if two mysql_type_info objects are equal.
inline bool operator ==(const mysql_type_info& a, const mysql_type_info& b)
{
	return a.id() == b.id();
}

/// \brief Returns true if two mysql_type_info objects are not equal.
inline bool operator !=(const mysql_type_info& a, const mysql_type_info& b)
{
	return a.id() != b.id();
}

/// \brief Returns true if a given mysql_type_info object is equal
/// to a given C++ type_info object.
inline bool operator ==(const std::type_info& a, const mysql_type_info& b)
{
	return a == b.c_type();
}

/// \brief Returns true if a given mysql_type_info object is not equal
/// to a given C++ type_info object.
inline bool operator !=(const std::type_info& a, const mysql_type_info& b)
{
	return a != b.c_type();
}

/// \brief Returns true if a given mysql_type_info object is equal
/// to a given C++ type_info object.
inline bool operator ==(const mysql_type_info& a, const std::type_info& b)
{
	return a.c_type() == b;
}

/// \brief Returns true if a given mysql_type_info object is not equal
/// to a given C++ type_info object.
inline bool operator !=(const mysql_type_info& a, const std::type_info& b)
{
	return a.c_type() != b;
}

}								// end namespace mysqlpp

#endif

Deleted lib/vallist.cpp.
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
















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/***********************************************************************
 vallist.cpp - Implements utility functions for building value lists.
	This is internal functionality used within the library.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "vallist.h"

#include "result.h"
#include "row.h"

using std::string;

namespace mysqlpp {

void
create_vector(size_t size, std::vector<bool>& v, bool t0, bool t1, bool t2,
		bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
		bool ta, bool tb, bool tc)
{
	v.reserve(size);

	v.push_back(t0);
	if (size == 1) return;

	v.push_back(t1);
	if (size == 2) return;

	v.push_back(t2);
	if (size == 3) return;

	v.push_back(t3);
	if (size == 4) return;

	v.push_back(t4);
	if (size == 5) return;

	v.push_back(t5);
	if (size == 6) return;

	v.push_back(t6);
	if (size == 7) return;

	v.push_back(t7);
	if (size == 8) return;

	v.push_back(t8);
	if (size == 9) return;

	v.push_back(t9);
	if (size == 10) return;

	v.push_back(ta);
	if (size == 11) return;

	v.push_back(tb);
	if (size == 12) return;

	v.push_back(tc);
}


template <class Container>
void create_vector(const Container& c, std::vector<bool>& v,
		std::string s0, std::string s1, std::string s2, std::string s3,
		std::string s4, std::string s5, std::string s6, std::string s7,
		std::string s8, std::string s9, std::string sa, std::string sb,
		std::string sc)
{
	v.insert(v.begin(), c.size(), false);

	v[c.parent().field_num(s0)] = true;
	if (s1.empty()) return;

	v[c.parent().field_num(s1)] = true;
	if (s2.empty()) return;

	v[c.parent().field_num(s2)] = true;
	if (s3.empty()) return;

	v[c.parent().field_num(s3)] = true;
	if (s4.empty()) return;

	v[c.parent().field_num(s4)] = true;
	if (s5.empty()) return;

	v[c.parent().field_num(s5)] = true;
	if (s6.empty()) return;

	v[c.parent().field_num(s6)] = true;
	if (s7.empty()) return;

	v[c.parent().field_num(s7)] = true;
	if (s8.empty()) return;

	v[c.parent().field_num(s8)] = true;
	if (s9.empty()) return;

	v[c.parent().field_num(s9)] = true;
	if (sa.empty()) return;

	v[c.parent().field_num(sa)] = true;
	if (sb.empty()) return;

	v[c.parent().field_num(sb)] = true;
	if (sc.empty()) return;

	v[c.parent().field_num(sc)] = true;
}


#if !defined(DOXYGEN_IGNORE)
// Instantiate above template.  Not sure why this is necessary.  Hide it
// from Doxygen, because we clearly cannot appease it by documenting it.
template void
create_vector(const Row& c, std::vector<bool>& v, string s0,
		string s1, string s2, string s3, string s4, string s5,
		string s6, string s7, string s8, string s9, string sa,
		string sb, string sc);
#endif

} // end namespace mysqlpp

Deleted lib/vallist.h.
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














































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// \file vallist.h
/// \brief Declares templates for holding lists of values.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#ifndef MYSQLPP_VALLIST_H
#define MYSQLPP_VALLIST_H

#include "manip.h"

#include <string>
#include <vector>

namespace mysqlpp {


/// \brief Holds two lists of items, typically used to construct a
/// SQL "equals clause".
///
/// The WHERE clause in a SQL SELECT statment is an example of an
/// equals clause.
///
/// Imagine an object of this type contains the lists (a, b) (c, d),
/// and that the object's delimiter and equals symbols are set to ", "
/// and " = " respectively.  When you insert that object into a C++
/// stream, you would get "a = c, b = d".
///
/// This class is never instantiated by hand.  The equal_list()
/// functions build instances of this structure template to do their
/// work.  MySQL++'s SSQLS mechanism calls those functions when
/// building SQL queries; you can call them yourself to do similar work.
/// The "Harnessing SSQLS Internals" section of the user manual has
/// some examples of this.
///
/// \sa equal_list_b

template <class Seq1, class Seq2, class Manip>
struct equal_list_ba
{
	/// \brief the list of objects on the left-hand side of the
	/// equals sign
	const Seq1* list1;

	/// \brief the list of objects on the right-hand side of the
	/// equals sign
	const Seq2* list2;

	/// \brief delimiter to use between each pair of elements
	const char* delem;

	/// \brief "equal" sign to use between each item in each equal
	/// pair; doesn't have to actually be " = "
	const char* equl;

	/// \brief manipulator to use when inserting the equal_list into
	/// a C++ stream
	Manip manip;

	/// \brief Create object
	///
	/// \param s1 list of objects on left-hand side of equal sign
	/// \param s2 list of objects on right-hand side of equal sign
	/// \param d what delimiter to use between each group in the list
	///		when inserting the list into a C++ stream
	/// \param e the "equals" sign between each pair of items in the
	/// 	equal list; doesn't actually have to be " = "!
	/// \param m manipulator to use when inserting the list into a
	/// 	C++ stream
	equal_list_ba(const Seq1& s1, const Seq2& s2, const char* d,
			const char* e, Manip m) :
	list1(&s1),
	list2(&s2),
	delem(d),
	equl(e),
	manip(m)
	{
	}
};


/// \brief Same as equal_list_ba, plus the option to have some elements
/// of the equals clause suppressed.
///
/// Imagine an object of this type contains the lists (a, b, c)
/// (d, e, f), that the object's 'fields' list is (true, false, true),
/// and that the object's delimiter and equals symbols are set to
/// " AND " and " = " respectively.  When you insert that object into a
/// C++ stream, you would get "a = d AND c = f".
///
/// See equal_list_ba's documentation for more details.

template <class Seq1, class Seq2, class Manip>
struct equal_list_b
{
	/// \brief the list of objects on the left-hand side of the
	/// equals sign
	const Seq1* list1;

	/// \brief the list of objects on the right-hand side of the
	/// equals sign
	const Seq2* list2;

	/// \brief for each true item in the list, the pair in that position
	/// will be inserted into a C++ stream
	const std::vector<bool> fields;

	/// \brief delimiter to use between each pair of elements
	const char* delem;

	/// \brief "equal" sign to use between each item in each equal
	/// pair; doesn't have to actually be " = "
	const char* equl;

	/// \brief manipulator to use when inserting the equal_list into
	/// a C++ stream
	Manip manip;

	/// \brief Create object
	///
	/// \param s1 list of objects on left-hand side of equal sign
	/// \param s2 list of objects on right-hand side of equal sign
	/// \param f for each true item in the list, the pair of items
	///		in that position will be inserted into a C++ stream
	/// \param d what delimiter to use between each group in the list
	///		when inserting the list into a C++ stream
	/// \param e the "equals" sign between each pair of items in the
	/// 	equal list; doesn't actually have to be " = "!
	/// \param m manipulator to use when inserting the list into a
	/// 	C++ stream
	equal_list_b(const Seq1& s1, const Seq2& s2,
			const std::vector<bool>& f, const char* d,
			const char* e, Manip m) :
	list1(&s1),
	list2(&s2),
	fields(f),
	delem(d),
	equl(e),
	manip(m)
	{
	}
};


/// \brief Holds a list of items, typically used to construct a SQL
/// "value list".
///
/// The SQL INSERT statement has a VALUES clause; this class can
/// be used to construct the list of items for that clause.
///
/// Imagine an object of this type contains the list (a, b, c), and
/// that the object's delimiter symbol is set to ", ".  When you
/// insert that object into a C++ stream, you would get "a, b, c".
///
/// This class is never instantiated by hand.  The value_list()
/// functions build instances of this structure template to do their
/// work.  MySQL++'s SSQLS mechanism calls those functions when
/// building SQL queries; you can call them yourself to do similar work.
/// The "Harnessing SSQLS Internals" section of the user manual has
/// some examples of this.
///
/// \sa value_list_b

template <class Seq, class Manip>
struct value_list_ba
{
	/// \brief set of objects in the value list
	const Seq* list;

	/// \brief delimiter to use between each value in the list when
	/// inserting it into a C++ stream
	const char* delem;

	/// \brief manipulator to use when inserting the list into a
	/// C++ stream
	Manip manip;

	/// \brief Create object
	///
	/// \param s set of objects in the value list
	/// \param d what delimiter to use between each value in the list
	///		when inserting the list into a C++ stream
	/// \param m manipulator to use when inserting the list into a
	/// 	C++ stream
	value_list_ba(const Seq& s, const char* d, Manip m) :
	list(&s),
	delem(d),
	manip(m)
	{
	}
};


/// \brief Same as value_list_ba, plus the option to have some elements
/// of the list suppressed.
///
/// Imagine an object of this type contains the list (a, b, c), that
/// the object's 'fields' list is (true, false, true), and that the
/// object's delimiter is set to ":".  When you insert that object
/// into a C++ stream, you would get "a:c".
///
/// See value_list_ba's documentation for more details.

template <class Seq, class Manip>
struct value_list_b
{
	/// \brief set of objects in the value list
	const Seq* list;

	/// \brief delimiter to use between each value in the list when
	/// inserting it into a C++ stream
	const std::vector<bool> fields;

	/// \brief delimiter to use between each value in the list when
	/// inserting it into a C++ stream
	const char* delem;

	/// \brief manipulator to use when inserting the list into a C++
	/// stream
	Manip manip;

	/// \brief Create object
	///
	/// \param s set of objects in the value list
	/// \param f for each true item in the list, the list item
	///		in that position will be inserted into a C++ stream
	/// \param d what delimiter to use between each value in the list
	///		when inserting the list into a C++ stream
	/// \param m manipulator to use when inserting the list into a
	/// 	C++ stream
	value_list_b(const Seq& s, const std::vector<bool>& f,
			const char* d, Manip m) :
	list(&s),
	fields(f),
	delem(d),
	manip(m)
	{
	}
};


/// \brief Inserts an equal_list_ba into an std::ostream.
///
/// Given two lists (a, b) and (c, d), a delimiter D, and an equals
/// symbol E, this operator will insert "aEcDbEd" into the stream.
///
/// See equal_list_ba's documentation for concrete examples.
///
/// \sa equal_list()

template <class Seq1, class Seq2, class Manip>
std::ostream& operator <<(std::ostream& o,
		const equal_list_ba<Seq1, Seq2, Manip>& el)
{
	typename Seq1::const_iterator i = el.list1->begin();
	typename Seq2::const_iterator j = el.list2->begin();

	while (1) {
		o << *i << el.equl << el.manip << *j;
		if ((++i == el.list1->end()) || (++j == el.list2->end())) {
			break;
		}
		o << el.delem;
	}

	return o;
}


/// \brief Same as operator<< for equal_list_ba, plus the option to
/// suppress insertion of some list items in the stream.
///
/// See equal_list_b's documentation for examples of how this works.

template <class Seq1, class Seq2, class Manip>
std::ostream& operator <<(std::ostream& o,
		const equal_list_b <Seq1, Seq2, Manip>& el)
{
	typename Seq1::const_iterator i = el.list1->begin();
	typename Seq2::const_iterator j = el.list2->begin();

	int k = 0;
	while (1) {
		if (el.fields[k++]) {
			o << *i << el.equl << el.manip << *j;
		}
		if ((++i == el.list1->end()) || (++j == el.list2->end())) {
			break;
		}
		if (el.fields[k]) {
			o << el.delem;
		}
	}

	return o;
}


/// \brief Inserts a value_list_ba into an std::ostream.
///
/// Given a list (a, b) and a delimiter D, this operator will insert
/// "aDb" into the stream.
///
/// See value_list_ba's documentation for concrete examples.
///
/// \sa value_list()

template <class Seq, class Manip>
std::ostream& operator <<(std::ostream& o,
		const value_list_ba<Seq, Manip>& cl)
{
	typename Seq::const_iterator i = cl.list->begin();

	while (1) {
		o << cl.manip << *i;
		if (++i == cl.list->end()) {
			break;
		}
		o << cl.delem;
	}

	return o;
}


/// \brief Same as operator<< for value_list_ba, plus the option to
/// suppress insertion of some list items in the stream.
///
/// See value_list_b's documentation for examples of how this works.

template <class Seq, class Manip>
std::ostream& operator <<(std::ostream& o,
		const value_list_b<Seq, Manip>& cl)
{
	typename Seq::const_iterator i = cl.list->begin();

	int k = 0;
	while (1) {
		if (cl.fields[k++]) {
			o << cl.manip << *i;
		}
		if (++i == cl.list->end()) {
			break; 
		}
		if (cl.fields[k]) {
			o << cl.delem; 
		}
	}

	return o;
}


/// \brief Create a vector of bool with the given arguments as values.
///
/// This function takes up to 13 bools, with the size parameter
/// controlling the actual number of parameters we pay attention to.
///
/// This function is used within the library to build the vector used
/// in calling the vector form of Row::equal_list(), Row::value_list(),
/// and Row::field_list().  See the "Harnessing SSQLS Internals" section
/// of the user manual to see that feature at work.

void create_vector(size_t size, std::vector<bool>& v, bool t0,
		bool t1 = false, bool t2 = false, bool t3 = false,
		bool t4 = false, bool t5 = false, bool t6 = false,
		bool t7 = false, bool t8 = false, bool t9 = false,
		bool ta = false, bool tb = false, bool tc = false);


/// \brief Create a vector of bool using a list of named fields.
///
/// This function is used with the ResUse and Result containers,
/// which have a field_num() member function that maps a field name
/// to its position number.  So for each named field, we set the
/// bool in the vector at the corresponding position to true.
///
/// This function is used within the library to build the vector used
/// in calling the vector form of Row::equal_list(), Row::value_list(),
/// and Row::field_list().  See the "Harnessing SSQLS Internals" section
/// of the user manual to see that feature at work.

template <class Container>
void create_vector(const Container& c, std::vector<bool>& v,
		std::string s0, std::string s1, std::string s2,
		std::string s3, std::string s4, std::string s5,
		std::string s6, std::string s7, std::string s8,
		std::string s9, std::string sa, std::string sb,
		std::string sc);



/// \brief Constructs a value_list_ba
///
/// This function returns a value list that uses the 'do_nothing'
/// manipulator.  That is, the items are not quoted or escaped in any
/// way.  See value_list(Seq, const char*, Manip) if you need to
/// specify a manipulator.
///
/// \param s an STL sequence of items in the value list
/// \param d delimiter operator<< should place between items

template <class Seq>
value_list_ba<Seq, do_nothing_type0>
value_list(const Seq& s, const char* d = ",")
{
	return value_list_ba<Seq, do_nothing_type0>(s, d, do_nothing);
}


/// \brief Constructs a value_list_ba
///
/// \param s an STL sequence of items in the value list
/// \param d delimiter operator<< should place between items
/// \param m manipulator to use when inserting items into a stream

template <class Seq, class Manip>
value_list_ba<Seq, Manip>
value_list(const Seq& s, const char* d, Manip m) 
{
	return value_list_ba<Seq, Manip>(s, d, m);
}


/// \brief Constructs a value_list_b (sparse value list)
///
/// \param s an STL sequence of items in the value list
/// \param d delimiter operator<< should place between items
/// \param m manipulator to use when inserting items into a stream
/// \param vb for each item in this vector that is true, the
/// corresponding item in the value list is inserted into a stream;
/// the others are suppressed

template <class Seq, class Manip>
inline value_list_b<Seq, Manip>
value_list(const Seq& s, const char* d, Manip m,
		const std::vector<bool>& vb) 
{
	return value_list_b<Seq, Manip>(s, vb, d, m);
}


/// \brief Constructs a value_list_b (sparse value list)
///
/// Same as value_list(Seq&, const char*, Manip, const vector<bool>&),
/// except that it takes the bools as arguments instead of wrapped up
/// in a vector object.

template <class Seq, class Manip>
value_list_b<Seq, Manip>
value_list(const Seq& s, const char* d, Manip m, bool t0,
		bool t1 = false, bool t2 = false, bool t3 = false,
		bool t4 = false, bool t5 = false, bool t6 = false,
		bool t7 = false, bool t8 = false, bool t9 = false,
		bool ta = false, bool tb = false, bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
				  ta, tb, tc);
	return value_list_b<Seq, Manip>(s, vb, d, m);
}

/// \brief Constructs a sparse value list
///
/// Same as value_list(Seq&, const char*, Manip, bool, bool...) but
/// without the Manip parameter.  We use the do_nothing manipulator,
/// meaning that the value list items are neither escaped nor quoted
/// when being inserted into a stream.

template <class Seq>
value_list_b<Seq, do_nothing_type0>
value_list(const Seq& s, const char* d, bool t0,
		bool t1 = false, bool t2 = false, bool t3 = false,
		bool t4 = false, bool t5 = false, bool t6 = false,
		bool t7 = false, bool t8 = false, bool t9 = false,
		bool ta = false, bool tb = false, bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
				  ta, tb, tc);
	return value_list_b<Seq, do_nothing_type0>(s, vb, d, do_nothing);
}


/// \brief Constructs a sparse value list
///
/// Same as value_list(Seq&, const char*, Manip, bool, bool...) but
/// without the Manip or delimiter parameters.  We use the do_nothing
/// manipulator, meaning that the value list items are neither escaped
/// nor quoted when being inserted into a stream.  The delimiter is a
/// comma.  This form is suitable for lists of simple data, such as
/// integers.

template <class Seq>
value_list_b<Seq, do_nothing_type0>
value_list(const Seq& s, bool t0,
		bool t1 = false, bool t2 = false, bool t3 = false,
		bool t4 = false, bool t5 = false, bool t6 = false,
		bool t7 = false, bool t8 = false, bool t9 = false,
		bool ta = false, bool tb = false, bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
				  ta, tb, tc);
	return value_list_b<Seq, do_nothing_type0>(s, vb, ",", do_nothing);
}


/// \brief Constructs an equal_list_ba
///
/// This function returns an equal list that uses the 'do_nothing'
/// manipulator.  That is, the items are not quoted or escaped in any
/// way when inserted into a stream.  See equal_list(Seq, Seq,
/// const char*, const char*, Manip) if you need a different
/// manipulator.
///
/// The idea is for both lists to be of equal length because
/// corresponding elements from each list are handled as pairs, but if
/// one list is shorter than the other, the generated list will have
/// that many elements.
///
/// \param s1 items on the left side of the equals sign when the
/// equal list is inserted into a stream
/// \param s2 items on the right side of the equals sign
/// \param d delimiter operator<< should place between pairs
/// \param e what operator<< should place between items in each pair;
/// by default, an equals sign, as that is the primary use for this
/// mechanism.

template <class Seq1, class Seq2>
equal_list_ba<Seq1, Seq2, do_nothing_type0>
equal_list(const Seq1& s1, const Seq2& s2, const char *d = ",",
		const char *e = " = ")
{
	return equal_list_ba<Seq1, Seq2, do_nothing_type0>(s1, s2, d,
			e, do_nothing);
}


/// \brief Constructs an equal_list_ba
///
/// Same as equal_list(Seq&, Seq&, const char*, const char*) except that
/// it also lets you specify the manipulator.  Use this version if the
/// data must be escaped or quoted when being inserted into a stream.

template <class Seq1, class Seq2, class Manip>
equal_list_ba<Seq1, Seq2, Manip>
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
		const char* e, Manip m)
{
	return equal_list_ba<Seq1, Seq2, Manip>(s1, s2, d, e, m);
}


/// \brief Constructs a equal_list_b (sparse equal list)
///
/// Same as equal_list(Seq&, Seq&, const char*, const char*, Manip) except
/// that you can pass a vector of bools. For each true item in that
/// list, operator<< adds the corresponding item is put in the equal
/// list.  This lets you pass in sequences when you don't want all of
/// the elements to be inserted into a stream.

template <class Seq1, class Seq2, class Manip>
equal_list_b<Seq1, Seq2, Manip>
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
		const char *e, Manip m, const std::vector<bool>& vb)
{
	return equal_list_b<Seq1, Seq2, Manip>(s1, s2, vb, d, e, m);
}


/// \brief Constructs a equal_list_b (sparse equal list)
///
/// Same as equal_list(Seq&, Seq&, const char*, const char*, Manip,
/// vector<bool>&) except that it takes boolean parameters
/// instead of a list of bools.

template <class Seq1, class Seq2, class Manip>
equal_list_b<Seq1, Seq2, Manip>
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
		const char* e, Manip m, bool t0, bool t1 = false,
		bool t2 = false, bool t3 = false, bool t4 = false,
		bool t5 = false, bool t6 = false, bool t7 = false,
		bool t8 = false, bool t9 = false, bool ta = false,
		bool tb = false, bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
				  t9, ta, tb, tc);
	return equal_list_b<Seq1, Seq2, Manip>(s1, s2, vb, d, e, m);
}


/// \brief Constructs a equal_list_b (sparse equal list)
///
/// Same as equal_list(Seq&, Seq&, const char*, const char*, Manip,
/// bool, bool...) except that it doesn't take the Manip argument.
/// It uses the do_nothing manipulator instead, meaning that none of
/// the elements are escaped when being inserted into a stream.

template <class Seq1, class Seq2>
equal_list_b<Seq1, Seq2, do_nothing_type0>
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
		const char* e, bool t0, bool t1 = false, bool t2 = false,
		bool t3 = false, bool t4 = false, bool t5 = false,
		bool t6 = false, bool t7 = false, bool t8 = false,
		bool t9 = false, bool ta = false, bool tb = false,
		bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
				  t9, ta, tb, tc);
	return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb,
			d, e, do_nothing);
}


/// \brief Constructs a equal_list_b (sparse equal list)
///
/// Same as equal_list(Seq&, Seq&, const char*, const char*, bool,
/// bool...) except that it doesn't take the second const char*
/// argument.  It uses " = " for the equals symbol.

template <class Seq1, class Seq2>
equal_list_b<Seq1, Seq2, do_nothing_type0>
equal_list(const Seq1& s1, const Seq2& s2, const char* d, bool t0,
		bool t1 = false, bool t2 = false, bool t3 = false,
		bool t4 = false, bool t5 = false, bool t6 = false,
		bool t7 = false, bool t8 = false, bool t9 = false,
		bool ta = false, bool tb = false, bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
				  t9, ta, tb, tc);
	return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb,
			d, " = ", do_nothing);
}


/// \brief Constructs a equal_list_b (sparse equal list)
///
/// Same as equal_list(Seq&, Seq&, const char*, bool, bool...) except
/// that it doesn't take the const char* argument.  It uses a comma for
/// the delimiter.  This form is useful for building simple equals
/// lists, where no manipulators are necessary, and the default
/// delimiter and equals symbol are suitable.

template <class Seq1, class Seq2>
equal_list_b<Seq1, Seq2, do_nothing_type0>
equal_list(const Seq1& s1, const Seq2& s2, bool t0, bool t1 = false,
		bool t2 = false, bool t3 = false, bool t4 = false,
		bool t5 = false, bool t6 = false, bool t7 = false,
		bool t8 = false, bool t9 = false, bool ta = false,
		bool tb = false, bool tc = false)
{
	std::vector<bool> vb;
	create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
				  t9, ta, tb, tc);
	return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb,
			",", " = ", do_nothing);
}

} // end namespace mysqlpp

#endif
Deleted libmysqlclient.def.
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




















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
LIBRARY LIBMYSQL.dll
EXPORTS
_dig_vec_lower DATA
_dig_vec_upper DATA
bmove_upp
client_errors DATA
delete_dynamic
free_defaults
get_defaults_files
getopt_compare_strings
getopt_ull_limit_value
handle_options
init_dynamic_array
insert_dynamic
int2str
is_prefix
list_add
list_delete
load_defaults
my_end
my_getopt_print_errors DATA
my_init
my_malloc
my_memdup
my_no_flags_free
my_path
my_print_help
my_print_variables
my_realloc
my_strdup
myodbc_remove_escape
mysql_affected_rows@4
mysql_autocommit
mysql_change_user
mysql_character_set_name
mysql_close@4
mysql_commit
mysql_data_seek@12
mysql_debug
mysql_disable_reads_from_master
mysql_disable_rpl_parse
mysql_dump_debug_info
mysql_embedded
mysql_enable_reads_from_master
mysql_enable_rpl_parse
mysql_eof
mysql_errno@4
mysql_error@4
mysql_escape_string@12
mysql_fetch_field@4
mysql_fetch_field_direct
mysql_fetch_fields
mysql_fetch_lengths@4
mysql_fetch_row@4
mysql_field_count
mysql_field_seek@8
mysql_field_tell
mysql_free_result@4
mysql_get_client_info@0
mysql_get_client_version
mysql_get_host_info
mysql_get_parameters
mysql_get_proto_info
mysql_get_server_info
mysql_get_server_version
mysql_hex_string
mysql_info@4
mysql_init@4
mysql_insert_id@4
mysql_kill
mysql_list_dbs
mysql_list_fields
mysql_list_processes
mysql_list_tables
mysql_master_query
mysql_more_results@4
mysql_next_result@4
mysql_num_fields@4
mysql_num_rows@4
mysql_odbc_escape_string
mysql_options@12
mysql_ping@4
mysql_query@8
mysql_read_query_result
mysql_real_connect@32
mysql_real_escape_string@16
mysql_real_query@12
mysql_refresh@8
mysql_rollback
mysql_row_seek
mysql_row_tell
mysql_rpl_parse_enabled
mysql_rpl_probe
mysql_rpl_query_type
mysql_select_db@8
mysql_send_query
mysql_set_character_set
mysql_set_local_infile_default
mysql_set_local_infile_handler
mysql_set_server_option@8
mysql_shutdown@8
mysql_slave_query
mysql_sqlstate
mysql_ssl_set@24
mysql_stat
mysql_stmt_affected_rows
mysql_stmt_attr_get
mysql_stmt_attr_set
mysql_stmt_bind_param
mysql_stmt_bind_result
mysql_stmt_close
mysql_stmt_data_seek
mysql_stmt_errno
mysql_stmt_error
mysql_stmt_execute
mysql_stmt_fetch
mysql_stmt_fetch_column
mysql_stmt_field_count
mysql_stmt_free_result
mysql_stmt_init
mysql_stmt_insert_id
mysql_stmt_num_rows
mysql_stmt_param_count
mysql_stmt_param_metadata
mysql_stmt_prepare
mysql_stmt_reset
mysql_stmt_result_metadata
mysql_stmt_row_seek
mysql_stmt_row_tell
mysql_stmt_send_long_data
mysql_stmt_sqlstate
mysql_stmt_store_result
mysql_store_result@4
mysql_thread_end
mysql_thread_id
mysql_thread_init
mysql_thread_safe
mysql_use_result@4
mysql_warning_count
set_dynamic
strcend
strcont
strdup_root
strfill
strinstr
strmake
strmov
strxmov
Deleted mysql++.bkl.
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






























































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
<?xml version="1.0"?>
<makefile>
	<requires version="0.1.9"/>
	<using module="datafiles"/>
	<include file="presets/simple.bkl"/>

	<set var="DDD">$(DOLLAR)$(DOLLAR)d</set>
	<set var="DDF">$(DOLLAR)$(DOLLAR)f</set>
	<set var="AND">&amp;&amp;</set>
	<set var="ZLIB">yes</set>

	<set var="THREAD_TYPE">single</set>
	<if cond="FORMAT in ['msvc6prj', 'mingw']">
		<set var="THREAD_TYPE">multi</set>
	</if>
		
    <option name="BUILD">
        <values>debug,release</values>
        <values-description>Debug,Release</values-description>
        <default-value>debug</default-value>
        <description>
            Type of compiled binaries
        </description>
    </option>

    <set var="DEBUGINFO">
        <if cond="BUILD=='debug'">on</if>
        <if cond="BUILD=='release'">off</if>
    </set>

	<set var="BUILDDOCS">yes</set>
	<set var="BUILDEXAMPLES">yes</set>
	<set var="BUILDLIBRARY">yes</set>
	<set var="HEADER_DIR">$(PREFIX)/include/mysql++</set>

	<if cond="BUILDLIBRARY=='yes'">
		<dll id="mysqlpp">
			<libname>mysqlpp</libname>
			<so_version>2.3.2</so_version>

			<sources>
				lib/coldata.cpp
				lib/connection.cpp
				lib/datetime.cpp
				lib/field_names.cpp
				lib/fields.cpp
				lib/field_types.cpp
				lib/manip.cpp
				lib/myset.cpp
				lib/mysql++.cpp
				lib/qparms.cpp
				lib/query.cpp
				lib/result.cpp
				lib/row.cpp
				lib/sql_string.cpp
				lib/string_util.cpp 
				lib/transaction.cpp
				lib/type_info.cpp
				lib/vallist.cpp
			</sources>

			<debug-info>$(DEBUGINFO)</debug-info>

			<threading>$(THREAD_TYPE)</threading>
			<cxx-rtti>on</cxx-rtti>
			<cxx-exceptions>on</cxx-exceptions>
			
			<install-to>$(LIBDIR)</install-to>
			
			<if cond="FORMAT=='msvc6prj'">
				<define>_UNICODE</define>
				<define>MYSQLPP_MAKING_DLL</define>
				<define>HAVE_MYSQL_SSL_SET</define>
				<include>"C:\Program Files\MySQL\MySQL Server 5.0\include"</include>
				<lib-path>C:\Program Files\MySQL\MySQL Server 5.0\lib\opt</lib-path>
				<sys-lib>libmysql</sys-lib>
			</if>

			<if cond="FORMAT=='mingw'">
				<define>_UNICODE</define>
				<define>MYSQLPP_NO_DLL</define>
				<define>HAVE_MYSQL_SSL_SET</define>
				<include>"C:\Program Files\MySQL\MySQL Server 5.0\include"</include>
				<lib-path>"C:\Program Files\MySQL\MySQL Server 5.0\lib\opt"</lib-path>
				<sys-lib>mysqlclient</sys-lib>
			</if>

			<if cond="FORMAT=='autoconf'">
				<depends>lib/custom.h</depends>
				<depends>lib/querydef.h</depends>

				<cxxflags>@PTHREAD_CFLAGS@</cxxflags>
				<include>.</include>
				<ldflags>@PTHREAD_LIBS@ @MYSQLPP_EXTRA_LIBS@</ldflags>
				<sys-lib>@MYSQL_C_LIB@</sys-lib>

				<if cond="ZLIB=='yes'">
					<sys-lib>z</sys-lib>
				</if>

				<modify-target target="uninstall">
					<command>
						rm -f $(DESTDIR)$(libdir)/$(DLLPREFIX)mysqlpp.$(SO_SUFFIX)
					</command>
					<command>
						for f in *.h ; do rm -f $(HEADER_DIR)/$(DDF) ; done
					</command>
					<command>rmdir $(HEADER_DIR)</command>
				</modify-target>
			</if>
		</dll>

		<data-files>
			<files>lib/*.h</files>
			<install-to>$(HEADER_DIR)</install-to>
		</data-files>
	</if>	<!-- build library -->

	<!-- Set up build options common to all examples -->
	<template id="examples">
		<if cond="BUILDLIBRARY=='yes'">
			<depends>mysqlpp</depends>
		</if>
	
		<threading>$(THREAD_TYPE)</threading>
		<cxx-rtti>on</cxx-rtti>
		<cxx-exceptions>on</cxx-exceptions>
		<debug-info>$(DEBUGINFO)</debug-info>

		<include>lib</include>

		<if cond="FORMAT in ['autoconf', 'mingw', 'gnu']">
			<lib-path>.</lib-path>
		</if>

		<if cond="FORMAT=='msvc6prj'">
			<define>_UNICODE</define>
			<lib-path>$(BUILD)</lib-path>
			<lib-path>C:\Program Files\MySQL\MySQL Server 5.0\lib\opt</lib-path>
			<include>"C:\Program Files\MySQL\MySQL Server 5.0\include"</include>
			<sys-lib>libmysql</sys-lib>
			<sys-lib>mysqlpp</sys-lib>
		</if>

		<if cond="FORMAT=='mingw'">
			<define>_UNICODE</define>
			<define>MYSQLPP_NO_DLL</define>
			<ldflags>
				-Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc
			</ldflags>
			<lib-path>..\lib</lib-path>
			<lib-path>"C:\Program Files\MySQL\MySQL Server 5.0\lib\opt"</lib-path>
			<include>"C:\Program Files\MySQL\MySQL Server 5.0\include"</include>
			<sys-lib>mysqlclient</sys-lib>
			<sys-lib>mysqlpp</sys-lib>
		</if>

		<if cond="FORMAT=='autoconf'">
			<cxxflags>@PTHREAD_CFLAGS@</cxxflags>
			<ldflags>@PTHREAD_LIBS@ @MYSQLPP_EXTRA_LIBS@</ldflags>
			<sys-lib>@MYSQL_C_LIB@</sys-lib>

			<warnings>max</warnings>
			<sys-lib>mysqlpp</sys-lib>
			<if cond="ZLIB=='yes'">
				<sys-lib>z</sys-lib>
			</if>
		</if>

		<if cond="FORMAT=='gnu'">
			<include>/usr/include/mysql</include>
			<include>/usr/include/mysql++</include>
			<sys-lib>mysqlpp</sys-lib>
			<sys-lib>mysqlclient</sys-lib>
		</if>
	</template>

	<!-- Additional options specific to examples that depend on
	     the util module. -->
	<template id="libutil-user">
		<depends>util</depends>
		<sys-lib>mysqlpp_util</sys-lib>
	</template>

	<!-- Define output targets, if exampless are enabled -->
	<if cond="BUILDEXAMPLES=='yes'">
		<!-- The "util" convenience library, used by the examples -->
		<lib id="util" template="examples">
			<libname>mysqlpp_util</libname>
			<sources>examples/util.cpp</sources>
		</lib>
		
		<!-- The examples themselves -->
		<exe id="resetdb" template="libutil-user,examples">
			<sources>examples/resetdb.cpp</sources>
		</exe>
		<exe id="simple1" template="libutil-user,examples">
			<sources>examples/simple1.cpp</sources>
		</exe>
		<exe id="simple2" template="libutil-user,examples">
			<sources>examples/simple2.cpp</sources>
		</exe>
		<exe id="simple3" template="libutil-user,examples">
			<sources>examples/simple3.cpp</sources>
		</exe>
		<exe id="multiquery" template="libutil-user,examples">
			<sources>examples/multiquery.cpp</sources>
		</exe>
		<exe id="tquery" template="libutil-user,examples">
			<sources>examples/tquery.cpp</sources>
		</exe>
		<exe id="usequery" template="libutil-user,examples">
			<sources>examples/usequery.cpp</sources>
		</exe>
		<exe id="custom1" template="libutil-user,examples">
			<sources>examples/custom1.cpp</sources>
		</exe>
		<exe id="custom2" template="libutil-user,examples">
			<sources>examples/custom2.cpp</sources>
		</exe>
		<exe id="custom3" template="libutil-user,examples">
			<sources>examples/custom3.cpp</sources>
		</exe>
		<exe id="custom4" template="libutil-user,examples">
			<sources>examples/custom4.cpp</sources>
		</exe>
		<exe id="custom5" template="libutil-user,examples">
			<sources>examples/custom5.cpp</sources>
		</exe>
		<exe id="custom6" template="libutil-user,examples">
			<sources>examples/custom6.cpp</sources>
		</exe>
		<exe id="dbinfo" template="libutil-user,examples">
			<sources>examples/dbinfo.cpp</sources>
		</exe>
		<exe id="fieldinf1" template="libutil-user,examples">
			<sources>examples/fieldinf1.cpp</sources>
		</exe>
		<exe id="load_jpeg" template="libutil-user,examples">
			<sources>examples/load_jpeg.cpp</sources>
		</exe>
		<exe id="xaction" template="libutil-user,examples">
			<sources>examples/xaction.cpp</sources>
		</exe>
		<exe id="store_if" template="libutil-user,examples">
			<sources>examples/store_if.cpp</sources>
		</exe>
		<exe id="for_each" template="libutil-user,examples">
			<sources>examples/for_each.cpp</sources>
		</exe>
		<exe id="cgi_jpeg" template="libutil-user,examples">
			<sources>examples/cgi_jpeg.cpp</sources>
		</exe>
	</if>	<!-- build examples -->

	<if cond="FORMAT=='autoconf'">
		<set var="PKGNAME">@PACKAGE_NAME@-@PACKAGE_VERSION@</set>

		<modify-target target="clean">
			<command>
				cd doc/html/refman ; \
				rm -f doxygen.css [a-z]*.{dot,html,map,md5,png} ; \
				rm -rf doc/latex doc/pdf
			</command>
		</modify-target>
			
		<action id="lib/custom.h">
			<command>cd lib ; ./custom.pl</command>
			<depends-on-file>lib/custom.pl</depends-on-file>
		</action>

		<action id="lib/querydef.h">
			<command>cd lib ; ./querydef.pl</command>
			<depends-on-file>lib/querydef.pl</depends-on-file>
		</action>

		<action id="tags">
			<is-phony/>
			<command>ctags `pwd`/{examples,lib}/*.{cpp,h}</command>
			<command>for d in examples lib ; do cd $(DDD) ; ln -sf ../tags . ; cd .. ; done</command>
		</action>
		<action id="ctags"><depends>tags</depends></action>

		<action id="doc/html/refman/index.html">
			<depends-on-file>lib/Doxyfile</depends-on-file>
			<depends-on-file>lib/*.cpp</depends-on-file>
			<depends-on-file>lib/*.h</depends-on-file>
			<command>
				mkdir -p doc/latex ; cd lib ; doxygen > /dev/null
			</command>
			<command>
				mkdir -p doc/pdf ; cd doc/latex ; make ; cp refman.pdf ../pdf
			</command>
		</action>

		<action id="doc/html/userman/index.html">
			<depends-on-file>doc/userman/userman.dbx</depends-on-file>
			<command>
				cd doc/userman ; make html pdf ; cp userman.pdf ../pdf
			</command>
		</action>

		<action id="doc">
			<depends>doc/html/refman/index.html</depends>
			<depends>doc/html/userman/index.html</depends>
		</action>

		<action id="dist">
			<if cond="BUILDDOCS=='yes'">
				<depends>doc</depends>
			</if>

			<!-- Set up package directory -->
			<command>
				for d in config doc/{.,html}/{refman,userman} examples lib ; \
				do \
					mkdir -p $(PKGNAME)/$(DDD) ; \
				done
			</command>

			<!-- Copy files into package directory -->
			<!-- top directory -->
			<command>
				cp Bakefiles.bkgen bootstrap ChangeLog cleanmf \
					config.guess config.h.in config.sub configure* \
					COPYING CREDITS exrun* HACKERS INSTALL install.bat \
					install-sh libmysqlclient.def LICENSE Makefile.* \
					mysql++.* mysql++_*.ds? osver README* rebake \
					reconf Wishlist $(PKGNAME)
			</command>

			<!-- config subdir -->
			<command>cp config/*.m4 $(PKGNAME)/config</command>

			<!-- doc subdir -->
			<if cond="BUILDDOCS=='yes'">
				<command>
					cp -r doc/README* doc/pdf doc/ssqls-pretty $(PKGNAME)/doc
				</command>
				<command>
					for f in LICENSE Makefile mktxt README *.{dbx,xsl} ; \
					do \
						cp doc/userman/$(DDF) $(PKGNAME)/doc/userman ; \
					done
				</command>
				<command>
					for d in refman userman ; do \
						for f in *.{css,html} ; do \
							cp doc/html/$(DDD)/$(DDF) $(PKGNAME)/doc/html/$(DDD) ; \
						done ; \
					done ; \
					cp doc/html/refman/*.png $(PKGNAME)/doc/html/refman
				</command>
			</if>
			<if cond="BUILDDOCS=='no'">
				<command>
					mkdir -p $(PKGNAME)/doc/html $(PKGNAME)/doc/pdf ;
					cp -r doc/README* doc/ssqls-pretty $(PKGNAME)/doc
				</command>
			</if>

			<!-- examples subdir -->
			<command>
				cp examples/*.{cpp,h,jpg} $(PKGNAME)/examples
			</command>
			<command>
				for d in mfc wforms ; \
				do \
					mkdir -p $(PKGNAME)/examples/vstudio/$(DDD) ; \
					cp examples/vstudio/$(DDD)/*.{cpp,h,r*,vcproj} \
						$(PKGNAME)/examples/vstudio/$(DDD) ; \
				done
			</command>

			<!-- lib subdir -->
			<command>
				cp lib/*.{cpp,h,in,pl} $(PKGNAME)/lib
			</command>

			<!-- distribution dir created, so pack up a copy and 
			     nuke the temporary -->
			<command>tar czf $(PKGNAME).tar.gz $(PKGNAME)</command>
			<command>rm -rf $(PKGNAME)</command>
		</action>

		<action id="rpm-setup">
			<command>cp $(PKGNAME).tar.gz /usr/src/redhat/SOURCES</command>
			<depends>dist</depends>
		</action>

		<action id="rpm">
			<command>cd /usr/src/redhat/SPECS</command>
			<command>rpmbuild -bb mysql++.spec</command>
			<depends>rpm-setup</depends>
		</action>

		<action id="srpm">
			<command>cd /usr/src/redhat/SPECS</command>
			<command>rpmbuild -bs mysql++.spec</command>
			<depends>rpm-setup</depends>
		</action>

		<action id="ebuild">
			<depends>dist</depends>
			<command>cp $(PKGNAME).tar.gz /usr/portage/distfiles</command>
			<command>
				cp mysql++.ebuild /usr/portage/dev-db/mysql++/$(PKGNAME).ebuild
			</command>
			<command>
				ebuild /usr/portage/dev-db/mysql++/$(PKGNAME).ebuild digest
			</command>
		</action>
	</if>
</makefile>
Deleted mysql++.ebuild.
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











































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

inherit gcc eutils gnuconfig

DESCRIPTION="C++ API interface to the MySQL database"
# This is the download page but includes links to other places
HOMEPAGE="http://tangentsoft.net/mysql++/"
SRC_URI_BASE="http://tangentsoft.net/mysql++/releases"
SRC_URI="${SRC_URI_BASE}/${P}.tar.gz"

LICENSE="LGPL-2"
SLOT="0"
KEYWORDS="x86 ~alpha ~hppa ~mips ~sparc ~ppc ~amd64"
IUSE=""

DEPEND=">=dev-db/mysql-3.23.49"

src_unpack() {
	unpack ${P}.tar.gz
}

src_compile() {
	gnuconfig_update
	# not including the directives to where MySQL is because it seems to find it
	# just fine without
	# force the cflags into place otherwise they get totally ignored by
	# configure
	CFLAGS="${CFLAGS}" CXXFLAGS="${CFLAGS} ${CXXFLAGS}" econf || \
			die "econf failed"

	emake || die "unable to make"
}

src_install() {
	make DESTDIR=${D} install || die
	# install the docs and HTML pages
	dodoc README LGPL
	dodoc doc/*
	dohtml doc/man-html/*
	prepalldocs
}

Deleted mysql++.spec.in.
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





























































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Summary:    C++ wrapper for the MySQL C API
Name:       @PACKAGE_NAME@
Version:    @PACKAGE_VERSION@
Release:    1%{?dist}
License:    LGPL
Group:      Development/Libraries
URL:        http://tangentsoft.net/mysql++/
Source0:    http://tangentsoft.net/mysql++/releases/mysql++-%{version}.tar.gz
BuildRoot:  %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
BuildRequires: MySQL-shared mysql-devel

%description
MySQL++ makes working with MySQL server queries as easy as working
with STL containers.  This package contains only the libraries needed to
run MySQL++-based programs.  If you are building your own MySQL++-based
programs, you also need to install the -devel package.

%package devel
Summary:   MySQL++ developer files (headers, examples, etc.)
Group:     Development/Libraries
Requires:  mysql++ = %{version}-%{release}, mysql-devel

%description devel
These are the files needed to compile MySQL++ based programs, plus
some sample code to get you started.  If you aren't building your own
programs, you probably don't need to install this package.

%package manuals
Summary:   MySQL++ user and reference manuals
Group:     Development/Libraries

%description manuals
This is the MySQL++ documentation.  It's a separate RPM just because
it's so large, and it doesn't change with every release.

%prep
%setup -q

%build
%configure --disable-dependency-tracking
%{__make} %{?_smp_mflags}

%install
rm -rf %{buildroot} doc/examples

%{__mkdir_p} %{buildroot}{%{_libdir},%{_includedir}}

%{__make} DESTDIR=%{buildroot} install

# Copy example programs to doc directory
%{__mkdir_p} doc/examples
%{__install} -m644 examples/*.{cpp,h} doc/examples/

# Fix up simple example Makefile to allow it to build on the install
# system, as opposed to the system where the Makefile was created.
%{__sed} -e 's@./examples/@@' \
  -e 's@^CPPFLAGS :=.*$@CPPFLAGS := $(shell mysql_config --cflags)@' \
  -e 's@^LDFLAGS :=.*$@LDFLAGS := $(shell mysql_config --libs)@' \
  -e 's@ -Ilib -I/usr/include/mysql@@' \
  Makefile.simple > doc/examples/Makefile

%clean
rm -rf %{buildroot} doc/examples

%post -p /sbin/ldconfig 

%postun -p /sbin/ldconfig

%files
%defattr(-,root,root,-)
%doc ChangeLog COPYING CREDITS LICENSE README
%{_libdir}/libmysqlpp.so.*

%files devel
%defattr(-,root,root,-)
%doc doc/examples doc/README.devel README.examples Wishlist
%{_includedir}/mysql++
%{_libdir}/libmysqlpp.so

%files manuals
%defattr(-,root,root,-)
%doc doc/html doc/pdf doc/README.manuals

%changelog
* Mon Jul 2 2007 Warren Young <mysqlpp@etr-usa.com> 2.3.0-1
- Reflected changes to doc dir layout in manuals sub-package

* Mon Mar 19 2007 Warren Young <mysqlpp@etr-usa.com> 2.2.1-4
- Reorganized locations of generated documentation

* Mon Mar 19 2007 Warren Young <mysqlpp@etr-usa.com> 2.2.1-3
- Merge of Remi Collet's spec file with official one

* Sun Mar 18 2007 Remi Collet <rpms@FamilleCollet.com> 2.2.1-2
- find perm on common.h
- soname mysql++-2.2.1-bkl.patch

* Wed Feb 28 2007 Remi Collet <rpms@FamilleCollet.com> 2.2.1-1
- Initial spec for Extras

* Wed Feb 28 2007 Remi Collet <rpms@FamilleCollet.com> 2.2.1-1.fc{3-6}.remi
- update to version 2.2.1

* Thu Jan 25 2007 Remi Collet <rpms@FamilleCollet.com> 2.2.0-1.fc{3-6}.remi
- update to version 2.2.0

* Mon Nov 13 2006 Remi Collet <rpms@FamilleCollet.com> 2.1.1.fc6.remi
- FC6.x86_64 build
- dynamic (sed) patch for Makefile (use mysql_config)

* Thu Nov 02 2006 Remi Collet <rpms@FamilleCollet.com> 2.1.1.fc6.remi
- FC6 build

* Sat Apr  8 2006 Remi Collet <rpms@FamilleCollet.com> 2.1.1.fc{3,4,5}.remi
- update to version 2.1.1

* Sat Nov 26 2005 Remi Collet <remi.collet@univ-reims.fr> 2.0.7-1.fc3.remi - 2.0.7-1.fc4.remi
- update to version 2.0.4
- build with mysql-5.0.15 (requires libmysqlclient.so.15)

* Sun Sep  4 2005 Remi Collet <remi.collet@univ-reims.fr> 2.0.4-1.FC4.remi
- version 2.0.4

* Sat Aug 20 2005 Remi Collet <remi.collet@univ-reims.fr> 2.0.2-1.FC4.remi
- built for FC4
- spec cleanning...

* Thu Jun 16 2005 Remi Collet <Remi.Collet@univ-reims.fr> 1.7.40-1.FC3.remi
- built for FC3 and MySQL 4.1.11
- examples in /usr/share/doc/mysql++-%%{version}/examples

* Sat Apr 30 2005 Warren Young <mysqlpp@etr-usa.com> 1.7.34-1
- Split manuals out into their own sub-package.

* Thu Mar 10 2005 Warren Young <mysqlpp@etr-usa.com> 1.7.32-1
- Disabled building of examples, to speed RPM build.

* Fri Nov 05 2004 Warren Young <mysqlpp@etr-usa.com> 1.7.21-1
- Split out -devel subpackage, which now includes the examples

* Wed Aug 18 2004 Warren Young <mysqlpp@etr-usa.com> 1.7.11-1
- Removed examples from documentation.
- Limited documentation to just the generated files, not the sources.

* Wed Apr 16 2003 Tuan Hoang <tqhoang@bigfoot.com> 1.7.9-4
- Added gcc 3.2.2 patch.
- Packaged using Red Hat Linux 8.0 and 9.

* Thu Nov 14 2002 Tuan Hoang <tqhoang@bigfoot.com> 1.7.9-3
- Changed the version passed to libtool.

* Mon Oct 28 2002 Tuan Hoang <tqhoang@bigfoot.com> 1.7.9-2
- Updated the version numbering of the library to be 1.7.9.
- Packaged using Red Hat Linux 8.0.

* Thu Oct 17 2002 Philipp Berndt <philipp.berndt@gmx.net>
- packaged
Deleted osver.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#!/bin/sh
if grep Red /etc/issue > /dev/null 2>&1
then
	echo -n rh
	grep Red /etc/issue |cut -f5 -d' '
elif grep Fedora /etc/issue > /dev/null 2>&1
then
	echo -n fc
	grep Fedora /etc/issue |cut -f4 -d' '
elif grep CentOS /etc/issue > /dev/null 2>&1
then
	echo -n el
	grep CentOS /etc/issue |cut -f3 -d' ' |cut -f1 -d.
else
	echo UNKNOWN
fi
Deleted rebake.
1
2
3
4




-
-
-
-
#!/bin/sh
set -x
bakefilize && bakefile_gen $* && mv autoconf_inc.m4 config
unix2dos *.ds? > /dev/null 2>&1
Deleted reconf.
1
2


-
-
#!/bin/sh
./configure --cache-file=config.cache $*
Added sqlplus-config.in.































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#!/bin/sh

prefix=@prefix@
exec_prefix=@exec_prefix@
exec_prefix_set=no

usage()
{
	cat <<EOF
Usage: $0 [OPTIONS] [LIBRARIES]
Options:
	[--prefix[=DIR]]
	[--exec-prefix[=DIR]]
	[--version]
	[--libs]
	[--cxxflags]
Libraries:
	sqlplus
EOF
	exit $1
}

if test $# -eq 0; then
	usage 1 1>&2
fi

while test $# -gt 0; do
  case "$1" in
  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
  *) optarg= ;;
  esac

  case $1 in
    --prefix=*)
      prefix=$optarg
      if test $exec_prefix_set = no ; then
        exec_prefix=$optarg
      fi
      ;;
    --prefix)
      echo_prefix=yes
      ;;
    --exec-prefix=*)
      exec_prefix=$optarg
      exec_prefix_set=yes
      ;;
    --exec-prefix)
      echo_exec_prefix=yes
      ;;
    --version)
      echo @SQLPLUS_VERSION@
      exit 0
      ;;
    --cxxflags)
      includes=""
      if test "@includedir@" != /usr/include ; then
        includes="-I@includedir@"
      fi
      includes="${includes} -I@includedir@/@PACKAGE@"
      echo_cxxflags=yes
      ;;
    --libs)
      echo_libs=yes
      ;;
    sqlplus)
      lib_sqlplus=yes
      ;;
    *)
      usage 1 1>&2
      ;;
  esac
  shift
done

if test "$echo_prefix" = "yes"; then
	echo $prefix
fi
if test "$echo_exec_prefix" = "yes"; then
	echo $exec_prefix
fi
if test "$echo_lock_dir" = "yes"; then
	echo $lock_dir
fi
if test "$echo_cxxflags" = "yes"; then
	cxxflags=""
	echo $includes $cxxflags
fi
if test "$echo_libs" = "yes"; then
	libsp=""
	libsa=""
	if test "$lib_sqlplus" = "yes"; then
		libsp="$libsp --lsqlplus"
	fi
	echo -L@libdir@ $libsp $libsa
fi
Added sqlplus.spec.in.







































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# -*- Mode:rpm-spec -*-
# mysql++.spec.in
Summary: C++ interface to MySQL database
%define rel 2

%define version @VERSION@
%define pkgname @PACKAGE@
%define prefix /usr

%define lt_release @LT_RELEASE@
%define lt_version @LT_CURRENT@.@LT_REVISION@.@LT_AGE@

Name: %{pkgname}
Version: %{version}
Release: %{rel}

Copyright: LGPL
Group: Applications/Databases
Source: %{pkgname}-%{version}.tar.gz
Requires: MySQL-server
Buildroot: /tmp/%{pkgname}-root
URL: http://mysql.com
Prefix: %{prefix}
Packager: Dale K. Hawkins <dhawkins@cdrgts.com>

%description
A C++ interface to the MySQL API.

%changelog
* Tue Jan  4 2000 Dale Hawkins <dhawkins@cdrgts.com>

- Added a spec.in file to work with autoconf and to support libtool's release mechanism

%prep
%setup
#%patch

%build
%GNUconfigure
# This is why we copy the CFLAGS to the CXXFLAGS in configure.in
# CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix}
make

%install
# To make things work with BUILDROOT
if [ "$RPM_BUILD_ROOT" != "/tmp/%{pkgname}-root" ]
then
  echo
  echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  echo @								    @
  echo @  RPM_BUILD_ROOT is not what I expected.  Please clean it yourself. @
  echo @								    @
  echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  echo
else
  echo Cleaning RPM_BUILD_ROOT: "$RPM_BUILD_ROOT"
  rm -rf "$RPM_BUILD_ROOT"
fi
make DESTDIR="$RPM_BUILD_ROOT" install

%clean
# Call me paranoid, but I do not want to be responsible for nuking
# someone's harddrive!
if [ "$RPM_BUILD_ROOT" != "/tmp/%{pkgname}-root" ]
then
  echo
  echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  echo @								    @
  echo @  RPM_BUILD_ROOT is not what I expected.  Please clean it yourself. @
  echo @								    @
  echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  echo
else
  echo Cleaning RPM_BUILD_ROOT: "$RPM_BUILD_ROOT"
  rm -rf "$RPM_BUILD_ROOT"
fi

%files
%defattr(-, root, root)
%{prefix}/lib/libsqlplus*.so*
%doc COPYRIGHT ChangeLog README AUTHORS NEWS
%doc doc/*

%post -p /sbin/ldconfig

%postun -p /sbin/ldconfig

%package devel
Summary: Development files for %{pkgname}
Group: Applications/Databases
%description devel
Development files for %{pkgname}.

%files devel
%defattr(-, root, root)
%{prefix}/lib/lib*.so
%{prefix}/lib/*a
%defattr(0775, root, root)
%{prefix}/bin/%{pkgname}-config
%dir %{prefix}/include/%{pkgname}
# IMHO, the examples should be installed as well
%doc examples/*.cc
%doc examples/*.hh
Added sqlplusint/Makefile.am.










































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
EXTRA_DIST = custom.pl

lib_LTLIBRARIES = libsqlplus.la

libsqlplus_la_SOURCES = coldata.cc connection.cc datetime.cc field_names.cc \
	field_types.cc manip.cc query.cc result.cc row.cc set.cc sql_query.cc \
	type_info.cc vallist.cc

libsqlplus_la_LDFLAGS = \
	-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
	-release $(LT_RELEASE)

noinst_HEADERS = magic.h tracker.h

# a little automake magic here; puts the headers in
# $(prefix)/include/$(package) good for projects such as this.  Let
# mysql++-config sort things out...
pkginclude_HEADERS = sqlplus.hh coldata1.hh coldata2.hh coldata3.hh coldata4.hh \
	compare1.hh compare2.hh compare3.hh connection0.hh connection1.hh \
	connection2.hh connection3.hh const_string1.hh const_string2.hh const_string3.hh \
	convert1.hh convert2.hh convert3.hh custom-macros.hh custom.hh datetime1.hh \
	datetime2.hh datetime3.hh field_names1.hh field_names2.hh field_names3.hh \
	field_types1.hh field_types2.hh field_types3.hh fields1.hh fields2.hh \
	manip1.hh manip2.hh manip3.hh null1.hh null2.hh null3.hh query1.hh query2.hh \
	query3.hh resiter1.hh result1.hh result2.hh result3.hh row1.hh row2.hh \
	row3.hh set1.hh set2.hh set3.hh sql_query0.hh sql_query1.hh sql_query2.hh \
	sql_query3.hh sql_string1.hh sql_string2.hh sql_string3.hh stream2string1.hh \
	stream2string2.hh stream2string3.hh tiny_int1.hh tiny_int2.hh tiny_int3.hh \
	type_info1.hh type_info2.hh type_info3.hh vallist1.hh vallist2.hh vallist3.hh \
	define_short defs undef_short

BUILT_SOURCES = custom.hh custom-macros.hh

custom.hh custom-macros.hh: custom.pl
	@PERL@ custom.pl

# These files should be removed by invoking maintainer-clean

# all-local: custom.hh custom-macros.hh

# distclean-local:
# 	rm -f custom.hh custom-macros.hh
Added sqlplusint/Makefile.in.













































































































































































































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# Makefile.in generated automatically by automake 1.4 from Makefile.am

# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.


SHELL = @SHELL@

srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@

bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include

DESTDIR =

pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@

top_builddir = ..

ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@

INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@

NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AS = @AS@
CC = @CC@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
LD = @LD@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@
LT_RELEASE = @LT_RELEASE@
LT_REVISION = @LT_REVISION@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
NM = @NM@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
PERL = @PERL@
RANLIB = @RANLIB@
SQLPLUS_BINARY_AGE = @SQLPLUS_BINARY_AGE@
SQLPLUS_INTERFACE_AGE = @SQLPLUS_INTERFACE_AGE@
SQLPLUS_MAJOR_VERSION = @SQLPLUS_MAJOR_VERSION@
SQLPLUS_MICRO_VERSION = @SQLPLUS_MICRO_VERSION@
SQLPLUS_MINOR_VERSION = @SQLPLUS_MINOR_VERSION@
VERSION = @VERSION@

EXTRA_DIST = custom.pl

lib_LTLIBRARIES = libsqlplus.la

libsqlplus_la_SOURCES = coldata.cc connection.cc datetime.cc field_names.cc 	field_types.cc manip.cc query.cc result.cc row.cc set.cc sql_query.cc 	type_info.cc vallist.cc


libsqlplus_la_LDFLAGS =  	-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) 	-release $(LT_RELEASE)


noinst_HEADERS = magic.h tracker.h

# a little automake magic here; puts the headers in
# $(prefix)/include/$(package) good for projects such as this.  Let
# mysql++-config sort things out...
pkginclude_HEADERS = sqlplus.hh coldata1.hh coldata2.hh coldata3.hh coldata4.hh 	compare1.hh compare2.hh compare3.hh connection0.hh connection1.hh 	connection2.hh connection3.hh const_string1.hh const_string2.hh const_string3.hh 	convert1.hh convert2.hh convert3.hh custom-macros.hh custom.hh datetime1.hh 	datetime2.hh datetime3.hh field_names1.hh field_names2.hh field_names3.hh 	field_types1.hh field_types2.hh field_types3.hh fields1.hh fields2.hh 	manip1.hh manip2.hh manip3.hh null1.hh null2.hh null3.hh query1.hh query2.hh 	query3.hh resiter1.hh result1.hh result2.hh result3.hh row1.hh row2.hh 	row3.hh set1.hh set2.hh set3.hh sql_query0.hh sql_query1.hh sql_query2.hh 	sql_query3.hh sql_string1.hh sql_string2.hh sql_string3.hh stream2string1.hh 	stream2string2.hh stream2string3.hh tiny_int1.hh tiny_int2.hh tiny_int3.hh 	type_info1.hh type_info2.hh type_info3.hh vallist1.hh vallist2.hh vallist3.hh 	define_short defs undef_short


BUILT_SOURCES = custom.hh custom-macros.hh
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES = 
LTLIBRARIES =  $(lib_LTLIBRARIES)


DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libsqlplus_la_LIBADD = 
libsqlplus_la_OBJECTS =  coldata.lo connection.lo datetime.lo \
field_names.lo field_types.lo manip.lo query.lo result.lo row.lo set.lo \
sql_query.lo type_info.lo vallist.lo
CXXFLAGS = @CXXFLAGS@
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
HEADERS =  $(noinst_HEADERS) $(pkginclude_HEADERS)

DIST_COMMON =  README Makefile.am Makefile.in


DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)

TAR = gtar
GZIP_ENV = --best
DEP_FILES =  .deps/coldata.P .deps/connection.P .deps/datetime.P \
.deps/field_names.P .deps/field_types.P .deps/manip.P .deps/query.P \
.deps/result.P .deps/row.P .deps/set.P .deps/sql_query.P \
.deps/type_info.P .deps/vallist.P
SOURCES = $(libsqlplus_la_SOURCES)
OBJECTS = $(libsqlplus_la_OBJECTS)

all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .cc .lo .o .s
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
	cd $(top_srcdir) && $(AUTOMAKE) --gnu sqlplusint/Makefile

Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
	cd $(top_builddir) \
	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status


mostlyclean-libLTLIBRARIES:

clean-libLTLIBRARIES:
	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)

distclean-libLTLIBRARIES:

maintainer-clean-libLTLIBRARIES:

install-libLTLIBRARIES: $(lib_LTLIBRARIES)
	@$(NORMAL_INSTALL)
	$(mkinstalldirs) $(DESTDIR)$(libdir)
	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
	    $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
	  else :; fi; \
	done

uninstall-libLTLIBRARIES:
	@$(NORMAL_UNINSTALL)
	list='$(lib_LTLIBRARIES)'; for p in $$list; do \
	  $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
	done

.s.o:
	$(COMPILE) -c $<

.S.o:
	$(COMPILE) -c $<

mostlyclean-compile:
	-rm -f *.o core *.core

clean-compile:

distclean-compile:
	-rm -f *.tab.c

maintainer-clean-compile:

.s.lo:
	$(LIBTOOL) --mode=compile $(COMPILE) -c $<

.S.lo:
	$(LIBTOOL) --mode=compile $(COMPILE) -c $<

mostlyclean-libtool:
	-rm -f *.lo

clean-libtool:
	-rm -rf .libs _libs

distclean-libtool:

maintainer-clean-libtool:

libsqlplus.la: $(libsqlplus_la_OBJECTS) $(libsqlplus_la_DEPENDENCIES)
	$(CXXLINK) -rpath $(libdir) $(libsqlplus_la_LDFLAGS) $(libsqlplus_la_OBJECTS) $(libsqlplus_la_LIBADD) $(LIBS)
.cc.o:
	$(CXXCOMPILE) -c $<
.cc.lo:
	$(LTCXXCOMPILE) -c $<

install-pkgincludeHEADERS: $(pkginclude_HEADERS)
	@$(NORMAL_INSTALL)
	$(mkinstalldirs) $(DESTDIR)$(pkgincludedir)
	@list='$(pkginclude_HEADERS)'; for p in $$list; do \
	  if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
	  echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p"; \
	  $(INSTALL_DATA) $$d$$p $(DESTDIR)$(pkgincludedir)/$$p; \
	done

uninstall-pkgincludeHEADERS:
	@$(NORMAL_UNINSTALL)
	list='$(pkginclude_HEADERS)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkgincludedir)/$$p; \
	done

tags: TAGS

ID: $(HEADERS) $(SOURCES) $(LISP)
	list='$(SOURCES) $(HEADERS)'; \
	unique=`for i in $$list; do echo $$i; done | \
	  awk '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	here=`pwd` && cd $(srcdir) \
	  && mkid -f$$here/ID $$unique $(LISP)

TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
	tags=; \
	here=`pwd`; \
	list='$(SOURCES) $(HEADERS)'; \
	unique=`for i in $$list; do echo $$i; done | \
	  awk '    { files[$$0] = 1; } \
	       END { for (i in files) print i; }'`; \
	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)

mostlyclean-tags:

clean-tags:

distclean-tags:
	-rm -f TAGS ID

maintainer-clean-tags:

distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)

subdir = sqlplusint

distdir: $(DISTFILES)
	here=`cd $(top_builddir) && pwd`; \
	top_distdir=`cd $(top_distdir) && pwd`; \
	distdir=`cd $(distdir) && pwd`; \
	cd $(top_srcdir) \
	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu sqlplusint/Makefile
	@for file in $(DISTFILES); do \
	  d=$(srcdir); \
	  if test -d $$d/$$file; then \
	    cp -pr $$/$$file $(distdir)/$$file; \
	  else \
	    test -f $(distdir)/$$file \
	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
	    || cp -p $$d/$$file $(distdir)/$$file || :; \
	  fi; \
	done

DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)

-include $(DEP_FILES)

mostlyclean-depend:

clean-depend:

distclean-depend:
	-rm -rf .deps

maintainer-clean-depend:

%.o: %.c
	@echo '$(COMPILE) -c $<'; \
	$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
	@-cp .deps/$(*F).pp .deps/$(*F).P; \
	tr ' ' '\012' < .deps/$(*F).pp \
	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
	    >> .deps/$(*F).P; \
	rm .deps/$(*F).pp

%.lo: %.c
	@echo '$(LTCOMPILE) -c $<'; \
	$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
	  < .deps/$(*F).pp > .deps/$(*F).P; \
	tr ' ' '\012' < .deps/$(*F).pp \
	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
	    >> .deps/$(*F).P; \
	rm -f .deps/$(*F).pp

%.o: %.cc
	@echo '$(CXXCOMPILE) -c $<'; \
	$(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
	@-cp .deps/$(*F).pp .deps/$(*F).P; \
	tr ' ' '\012' < .deps/$(*F).pp \
	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
	    >> .deps/$(*F).P; \
	rm .deps/$(*F).pp

%.lo: %.cc
	@echo '$(LTCXXCOMPILE) -c $<'; \
	$(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
	  < .deps/$(*F).pp > .deps/$(*F).P; \
	tr ' ' '\012' < .deps/$(*F).pp \
	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
	    >> .deps/$(*F).P; \
	rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am: install-libLTLIBRARIES
install-exec: install-exec-am

install-data-am: install-pkgincludeHEADERS
install-data: install-data-am

install-am: all-am
	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
uninstall: uninstall-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
all-redirect: all-am
install-strip:
	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
	$(mkinstalldirs)  $(DESTDIR)$(libdir) $(DESTDIR)$(pkgincludedir)


mostlyclean-generic:

clean-generic:

distclean-generic:
	-rm -f Makefile $(CONFIG_CLEAN_FILES)
	-rm -f config.cache config.log stamp-h stamp-h[0-9]*

maintainer-clean-generic:
	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean-am:  mostlyclean-libLTLIBRARIES mostlyclean-compile \
		mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
		mostlyclean-generic

mostlyclean: mostlyclean-am

clean-am:  clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
		clean-depend clean-generic mostlyclean-am

clean: clean-am

distclean-am:  distclean-libLTLIBRARIES distclean-compile \
		distclean-libtool distclean-tags distclean-depend \
		distclean-generic clean-am
	-rm -f libtool

distclean: distclean-am

maintainer-clean-am:  maintainer-clean-libLTLIBRARIES \
		maintainer-clean-compile maintainer-clean-libtool \
		maintainer-clean-tags maintainer-clean-depend \
		maintainer-clean-generic distclean-am
	@echo "This command is intended for maintainers to use;"
	@echo "it deletes files that may require special tools to rebuild."

maintainer-clean: maintainer-clean-am

.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
distclean-compile clean-compile maintainer-clean-compile \
mostlyclean-libtool distclean-libtool clean-libtool \
maintainer-clean-libtool uninstall-pkgincludeHEADERS \
install-pkgincludeHEADERS tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir mostlyclean-depend \
distclean-depend clean-depend maintainer-clean-depend info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean


custom.hh custom-macros.hh: custom.pl
	@PERL@ custom.pl

# These files should be removed by invoking maintainer-clean

# all-local: custom.hh custom-macros.hh

# distclean-local:
# 	rm -f custom.hh custom-macros.hh

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
Added sqlplusint/README.










































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
All of the header files in this directory (sqlplusint) are internal.
This means that you should never include any of these directly in your
programs as they are subject to change from one releases to another.

For those interesting in improving the code the files are laid out in
the following fashion:

name0.hh: Header files ending in a 0.hh generally contains macro
  definitions and other messy stuff.

name1.hh: Header files ending in 1.hh contain just the class as
  functions declarations and really simple inline functions.  A 1.hh
  header file should never include anything but other 1.hh header
  files. 

name2.hh: Header files ending in 2.hh contain inline functions and
  methods.  They should generally only include other 1.hh or 2.hh
  header files however they may also include 3.hh and 4.hh header
  files if, for example, they want to instantiate the necessary
  template functions.

name3.hh: Header files ending in 3.hh contain non-inline template
  functions and methods.

name4.hh: Header files ending in 4.hh contain template functions in
  which are the necessary instances should already be
  instantiated. Thus these should never be included in the end users
  program.  Only within other 4.hh or .cc files in this directory.

name.cc: These contain the actual functions and methods corresponding
  the the appropriate header file.  They may include templates
  provided that the necessary instances will all be instantiated by
  the end of the .cc file

The name1.hh, name2.hh, and name3.hh are all guaranteed to exists if
at least one of them exists so that I don't have to worry about
checking if they exists.  However, they files may contain nothing but

  #include"name<prev number.hh" 

I chose this format to minimize interdependencies and to help better
organize my code.
Added sqlplusint/coldata.cc.






1
2
3
4
5
6
+
+
+
+
+
+
#include <string>
#include "const_string3.hh"
#include "coldata4.hh"

template class mysql_ColData<string>;
template class mysql_ColData<const_string>;
Added sqlplusint/coldata1.hh.














































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __coldata1_hh__
#define __coldata1_hh__

#include <typeinfo>
#include <string>
#include "defs"
#include "type_info1.hh"
#include "const_string1.hh"
#include "null1.hh"

//! with_class = mysql_ColData

//: Exception structure thrown when a bad conversion takes place
struct BadConversion {
  const char*  type_name;  //:
  const string data;       //:
  size_t       retrieved;  //:
  size_t       actual_size;//:
  BadConversion(const char* tn, const char* d, size_t r, size_t a)
    : type_name(tn), data(d), retrieved(r), actual_size(a) {};
};

//: Base class for auto-converting column data.  Do not use directly. 
//
// A smart string. It will automatically convert it self to any of the
// basic C types. 
//
// When used with binary operators it will
// automatically convert it self to the type used on the other side of
// the operator if it is a basic type.
//
// However, be careful when using it with binary operators as. 
// 
// MysqlStr("12.86") + 2
// 
// will return 14 because 2 is an integer. What you wanted to say was 
//
// MysqlStr("12.86") + 2.0
//
// If this type of thing scares you define the micro NO_BINARY_OPERS
// to turn of this behavior.
//
// This class also has some basic information about the type of data
// stored in it.
//
// <bf>Do not use this class directly.</bf>
//  Use the typedef ColData or MutableColData instead.
template <class Str>
class mysql_ColData : public Str {
private:
  mysql_type_info _type;
	string buf;
public:
  mysql_ColData (mysql_type_info t = mysql_type_info::string_type) 
    : _type(t) {}
  mysql_ColData (const char *str, 
		 mysql_type_info t = mysql_type_info::string_type)
    : Str(str), _type(t) {buf=(string)str;}

  mysql_type_info type() {return _type;}
  //: Returns the current mysql type of current item

  bool quote_q() const {return _type.quote_q();}
  //: Returns true or false depending on if the data is of a type that
  //: should be quoted

  bool escape_q() const {return _type.escape_q();}
  //: Returns true of false depending on if the data is of a type that
  //: should be escaped
  
  template<class Type> Type conv (Type dummy) const;

  //!dummy: operator TYPE() const;
  //: Converts the column data to TYPE.
  // If all the charters are not read during the conversion to TYPE it
  // will through BadConversion.
  //
  // TYPE is defined for all the build in types.
  //
  // (Note, This is not an actual template)

  operator cchar*() const {return buf.c_str();}
  operator  signed char() const {return conv((signed char)0);}
  operator  unsigned char() const {return conv((unsigned char)0);}
  operator  int() const {return conv((int)0);}
  operator  unsigned int() const {return conv((unsigned int)0);}
  operator  short int() const {return conv((short int)0);}
  operator  unsigned short int() const {return conv((unsigned short int)0);}
  operator  long int() const {return conv((long int)0);}
  operator  unsigned long int() const {return conv((unsigned long int)0);}
#ifndef NO_LONG_LONGS
  operator  long long int() const {return conv((long long int)0);}
  operator  unsigned long long int() const {return conv((unsigned long long int)0);}
#endif
  operator  float() const {return conv((float)0);}
  operator  double() const {return conv((double)0);}

  template <class T, class B> operator Null<T,B> () const;
};

//: The Type that is returned by constant rows
typedef mysql_ColData<const_string> ColData;
//: The Type that is returned by mutable rows
typedef mysql_ColData<string>       MutableColData;
//: For backwards compatibility. Do not use.
typedef ColData MysqlString;
//: For backwards compatibility. Do not use.
typedef ColData MysqlStr;

#endif
Added sqlplusint/coldata2.hh.




















































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __coldata2_hh__
#define __coldata2_hh__

#include <stdlib.h>
#include "coldata1.hh"

#ifndef NO_BINARY_OPERS

#define oprsw(opr, other, conv) \
  template<class Str> \
  inline other operator opr (mysql_ColData<Str> x, other y) \
    {return (conv)x opr y;} \
  template<class Str> \
  inline other operator opr (other x, mysql_ColData<Str> y) \
    {return x opr (conv)y;}

#define operator_binary(other, conv) \
  oprsw(+, other, conv) \
  oprsw(-, other, conv) \
  oprsw(*, other, conv) \
  oprsw(/, other, conv) 

#define operator_binary_int(other, conv) \
  operator_binary(other, conv) \
  oprsw(%, other, conv) \
  oprsw(&, other, conv) \
  oprsw(^, other, conv) \
  oprsw(|, other, conv) \
  oprsw(<<, other, conv) \
  oprsw(>>, other, conv) 

operator_binary(float, double)
operator_binary(double, double)

operator_binary_int(char,long int)
operator_binary_int(int, long int)
operator_binary_int(short int, long int)
operator_binary_int(long int, long int)

operator_binary_int(unsigned char, unsigned long int)
operator_binary_int(unsigned int, unsigned long int)
operator_binary_int(unsigned short int, unsigned long int)
operator_binary_int(unsigned long int, unsigned long int)

#ifndef NO_LONG_LONGS
operator_binary_int(long long int, long long int)
operator_binary_int(unsigned long long int, unsigned long long int)
#endif 

#endif // NO_BINARY_OPERS

#endif
Added sqlplusint/coldata3.hh.
























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __coldata3_hh__
#define __coldata3_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <mysql.h>
#include <string>
#include "coldata2.hh"
#include "convert3.hh"
#include "null3.hh"

template <class Str> template <class T, class B> 
mysql_ColData<Str>::operator Null<T,B> () const {
  if ((*this)[0] == 'N' && (*this)[1] == 'U' && 
      (*this)[2] == 'U' && (*this)[3] == 'L' && size() == 4)
    return Null<T,B>(null);
  else return Null<T,B>(conv(T()));
}

#endif
Added sqlplusint/coldata4.hh.
























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __coldata4_h__
#define __coldata4_h__

#include "convert3.hh"

#include "coldata3.hh"

template <class Str> template<class Type> 
Type mysql_ColData<Str>::conv (Type dummy) const {
  size_t len = size();
  const char *str = c_str();
  const char *end = str;
  Type num = mysql_convert<Type>(str, end);
  if (*end == '.') {
    end++;
    for (;*end == '0'; end++);
  }
  if (*end != '\0' && end != NULL ) {
    throw BadConversion (typeid(Type).name(), c_str(), end - str, len);
  }
  return num;
}

#endif
Added sqlplusint/compare1.hh.













































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __compare1_hh__
#define __compare1_hh__

#include <function.h>
#include "row1.hh"

template <class BinaryPred, class CmpType>
class MysqlCmp : public unary_function<const MysqlRow&, bool>
{
protected:
  unsigned int index;
  BinaryPred   func;
  CmpType      cmp2;
public:
  MysqlCmp(uint i, const BinaryPred &f, const CmpType &c) : index(i),func(f),cmp2(c) {}
  bool operator () (const MysqlRow& cmp1) const {return func(cmp2,cmp1[index]);}
};

template <class BinaryPred>
class MysqlCmpCStr : public MysqlCmp<BinaryPred, const char *>
{
public:
  MysqlCmpCStr(uint i, const BinaryPred &f, const char* c) : MysqlCmp<BinaryPred, const char *> (i,f,c) {}
  bool operator () (const MysqlRow& cmp1) const 
    {return func(cmp2,cmp1[index]);}
};

//: A special function for using in find_if function where i is the field index number.
// This is a more generic form of mysql_cmp_cstr will work with any
// CmpType that MysqlString can convert to.  However, this is not
// neary as effecent.  Only use when obsoletely nessary.
template <class BinaryPred, class CmpType>
MysqlCmp <BinaryPred, CmpType>
mysql_cmp(uint i, const BinaryPred &func, const CmpType &cmp2)
{
  return MysqlCmp<BinaryPred, CmpType>(i, func, cmp2);
}

typedef binary_function<const char*, const char*, bool> bin_char_pred;

struct cstr_equal_to : bin_char_pred {
  bool operator () (const char *x, const char *y) const
    {return !strcmp(x,y);}
};
struct cstr_not_equal_to : bin_char_pred {
  bool operator () (const char *x, const char *y) const
    {return strcmp(x,y);}
};
struct cstr_less : bin_char_pred {
  bool operator () (const char *x, const char *y) const
    {return strcmp(x,y) > 0; }
};
struct cstr_less_equal : bin_char_pred {
  bool operator () (const char *x, const char *y) const
    {return strcmp(x,y) >= 0; }
};
struct cstr_greater : bin_char_pred {
  bool operator () (const char *x, const char *y) const
    {return strcmp(x,y) < 0; }
};
struct cstr_greater_equal : bin_char_pred {
  bool operator () (const char *x, const char *y) const
    {return strcmp(x,y) <= 0; }
};

//:A special function for using in find_if fucntion where i is the field index
//:number.
//
// func should be one of cstr_equal_to(), cstr_not_equal_to(),
// cstr_less(), cstr_less_equal(), cstr_less_equal(), cstr_less_equal().
template <class BinaryPred>
MysqlCmpCStr <BinaryPred>
mysql_cmp_cstr (uint i, const BinaryPred &func, const char *cmp2) {
  return MysqlCmpCStr<BinaryPred>(i, func, cmp2);
}

#endif
Added sqlplusint/compare2.hh.


1
2
+
+

#include "compare1.hh"
Added sqlplusint/compare3.hh.


1
2
+
+

#include "compare2.hh"
Added sqlplusint/connection.cc.










































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "connection3.hh"
#include "result3.hh"

// pointer_tracker<MYSQL,Connection>  Connection::others = pointer_tracker<MYSQL, Connection>();

Connection::Connection (const char *db, const char *host, const char *user, 
			const char *passwd, bool te) 
  : throw_exceptions(te), locked(false)
{
	mysql_init(&mysql);
  if (connect (db, host, user, passwd))
	{
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }

//  others.insert(&mysql,this);
}

Connection::Connection (const char *db, const char *host, const char *user, 
			const char *passwd, uint port, my_bool compress,
			unsigned int connect_timeout, bool te,
			const char *socket_name)
  : throw_exceptions(te), locked(false)
{
	mysql_init(&mysql);
  if (real_connect (db, host, user, passwd, port, compress,		connect_timeout,socket_name))
  {
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
//  others.insert(&mysql,this);
}

bool Connection::real_connect (cchar *db, cchar *host, cchar *user,
			       cchar *passwd, uint port, my_bool compress,
			       unsigned int connect_timeout,
			       const char *socket_name)
{
  if (socket_name && socket_name[0])
    mysql.options.unix_socket = (char *)socket_name;
  else
    mysql.options.unix_socket=NULL;
  mysql.options.port = port;
  mysql.options.compress = compress;
  mysql.options.connect_timeout=connect_timeout;
  locked = true; 
  if (mysql_connect(&mysql, host, user, passwd))
  {
    locked = false;
    Success = is_connected = true;
  }
  else
  {
    locked = false; Success = is_connected = false;
    if (throw_exceptions) throw BadQuery(error());
  }
  if (!Success) return Success;
  if (db[0]) // if db is not empty
    Success = select_db(db);
  return Success;
}

Connection::~Connection () {
  for (set<MysqlChild*>::iterator i = children.begin(); 
       i != children.end();
       i++) 
    {
      (*i)->parent_leaving();
    }
	mysql_close(&mysql);
//  others.remove(&mysql,this); 
}

bool Connection::select_db (const char *db) {
  bool suc = !(mysql_select_db(&mysql, db));
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::reload() {
  bool suc = !mysql_reload(&mysql);
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}

bool Connection::shutdown () {
  bool suc = !(mysql_shutdown(&mysql));
  if (throw_exceptions && !suc) throw MysqlBadQuery(error());
  else return suc;
}  

bool Connection::connect (cchar *db, cchar *host, cchar *user, cchar *passwd) {
  locked = true;
  if (mysql_connect(&mysql, host, user, passwd)) {
    locked = false;
    Success = is_connected = true;
  } else {
    locked = false;
    if (throw_exceptions) throw BadQuery(error());
    Success = is_connected = false;
  }
  if (!Success) return Success;
  if (db[0]) // if db is not empty
    Success = select_db(db);
  return Success;
}

string Connection::info () {
  char *i = mysql_info(&mysql);
  if (!i)
    return string();
  else
    return string(i);
}

ResNSel Connection::execute(const string &str, bool throw_excptns) {
  Success = false;
  if (lock()) 
    if (throw_excptns) throw BadQuery(error());
    else return ResNSel();
  Success = !mysql_query(&mysql, str.c_str()); 
  unlock();
  if (!Success) 
    if (throw_excptns) throw BadQuery(error());
    else return ResNSel();
  return ResNSel(this);
}

Result Connection::store(const string &str, bool throw_excptns) {
  Success = false;
  if (lock()) 
    if (throw_excptns) throw BadQuery(error());
    else return Result();
  Success = !mysql_query(&mysql, str.c_str()); 
  unlock();
  if (!Success) 
    if (throw_excptns) throw BadQuery(error());
    else return Result();
  return Result(mysql_store_result(&mysql));
}
  
ResUse Connection::use(const string &str, bool throw_excptns) {
  Success = false;
  if (lock()) 
    if (throw_excptns) throw BadQuery(error());
    else return ResUse();
  Success = !mysql_query(&mysql, str.c_str()); 
  if (!Success) 
    if (throw_excptns) throw BadQuery(error());
    else return ResUse();
  return ResUse(mysql_use_result(&mysql), this);
}

void Connection::storein(MutableRes& con, const string &s) {
  con = use(s);
}


Added sqlplusint/connection0.hh.













1
2
3
4
5
6
7
8
9
10
11
12
13
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __connection0_hh__
#define __connection0_hh__

class MysqlChild {
public:
  virtual void parent_leaving() = 0;
  virtual ~MysqlChild() {}
};

#endif



Added sqlplusint/connection1.hh.




































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __connection1_hh__
#define __connection1_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <mysql.h>
#include <vector.h>
#include <deque.h>
#include <list.h>
#include <slist.h>
#include <set.h>
#include <map.h>
#include <multiset.h>
#include "define_short"
#include "query1.hh"
#include "result1.hh"

#include "connection0.hh" 
#include "tracker.h"

//: Exception thrown when a BadQuery is encountered
struct BadQuery {
  BadQuery(string er) : error(er) {}
  string error; //: The error message
};

class MutableRes;

//: The main database handle
class Connection {
  friend ResNSel;
  friend ResUse;
  friend Query;
  
private:
  set<MysqlChild*> children;
//  static pointer_tracker<MYSQL, Connection> others;
  
  bool throw_exceptions;
  MYSQL mysql;
  bool is_connected;
  bool locked;
  bool Success;

  int          affected_rows()  {return mysql_affected_rows((MYSQL*) &mysql);}
  int          insert_id () {return mysql_insert_id(&mysql);}

public:
  Connection () : throw_exceptions(false), locked(false) //:
    {/* others.insert(&mysql,this);*/	mysql_init(&mysql);}
  Connection (bool te) : throw_exceptions(te), is_connected(false), locked(false), Success(false) //:
    {/*others.insert(&mysql,this);*/	mysql_init(&mysql);}
  Connection (const char *db, const char *host = "", const char *user = "", 
	      const char *passwd = "", bool te = false); 
  Connection (const char *db, const char *host, const char *user, 
	      const char *passwd = "", uint port = 3306, my_bool compress = 1,
	      unsigned int connect_timeout = 5, bool te = false,
	      cchar *socket_name = "");

  bool   real_connect (cchar *db = "", cchar *host = "", 
		       cchar *user = "", cchar *passwd = "", uint port = 0,
		       my_bool compress = 0, unsigned int connect_timeout = 60,
		       cchar *socket_name= "");
				
  ~Connection (); //:
  void         close() {mysql_close(&mysql);}	
  string       info ();	

  bool   connected() const {return is_connected;}
  //: returns true if a successful connection was made

  bool   success() {return Success;}
  //: returns true of the last query was successful

  bool   connect (cchar *db = "", cchar *host = "", 
		  cchar *user = "", cchar *passwd = "");
  //:

  bool   lock() {if (locked) return true; locked = true; return false;}
  void   unlock() {locked = false;}

  void purge (MYSQL *m) {mysql_close(&mysql); }
  //:

  void add_child(MysqlChild *child) {children.insert(child);}
  //:

  void remove_child(MysqlChild *child) {children.erase(child); }
  //: 

  inline Query query();
  //:

  operator bool () {return success();}                  //: returns success()
  string error () {return string(mysql_error(&mysql));} //: last error message()
	int errnum () {return mysql_errno(&mysql);}
	int   refresh (unsigned int refresh_options){ return mysql_refresh (&mysql,refresh_options); }
	int ping (void) { return mysql_ping(&mysql);}
	int kill (unsigned long pid) { return mysql_kill (&mysql,pid);}
  string clinet_info () {return string(mysql_get_client_info());} //:
  
  string host_info () {return string(mysql_get_host_info(&mysql));} //:
  
  int    proto_info () {return mysql_get_proto_info(&mysql);} //:
  
  string server_info () {return string(mysql_get_server_info(&mysql));} //:
 
  string stat() {return string(mysql_stat(&mysql));} //:
 
  Result  store(const string &str) {return store(str, throw_exceptions);} //:
  ResUse  use(const string &str)   {return use(str, throw_exceptions);} //:
  ResNSel execute(const string &str) {return execute(str, throw_exceptions);} //:
  Result  store(const string &str, bool te); //:
  ResUse  use(const string &str, bool te); //:
  ResNSel execute(const string &str, bool te); //:
 
  bool   create_db (string db) {return !(execute( "CREATE DATABASE " + db ));} //:
  bool   drop_db (string db) {return !(execute( "DROP DATABASE " + db ));} //:
  bool   select_db (string db) {return select_db(db.c_str());} //:
  bool   select_db (const char *db); //:
  bool   reload(); //:
  bool   shutdown (); //:
	string infoo (void) {return info ();}
	st_mysql_options get_options (void) const {return mysql.options;}
	int read_options(enum mysql_option option,const char *arg) {return  mysql_options(&mysql, option,arg);}

  template <class Sequence> void storein_sequence(Sequence &, const string &); //:
  template <class Set>      void storein_set(Set &, const string &);  //:

  //!dummy: void storein(TYPE &con, const string &s);
  //: Stores the results in TYPE.  
  // Stores the result in TYPE. TYPE must be some sort of STL container.  

                            void storein(MutableRes &con, const string &s);
  template <class T>        void storein(vector<T> &con, const string &s)
    {storein_sequence(con,s);}
  template <class T>        void storein(deque<T> &con, const string &s)
     {storein_sequence(con,s);}
  template <class T>        void storein(list<T> &con, const string &s)
    {storein_sequence(con,s);}
  template <class T>        void storein(slist<T> &con, const string &s)
    {storein_sequence(con,s);}
  template <class T>        void storein(set<T> &con, const string &s)
    {storein_set(con,s);}
  template <class T>        void storein(multiset<T> &con, const string &s)
    {storein_set(con,s);}
};


//! with_class = Connection

//: For backwards companablity, don't use
typedef Connection Mysql;

#endif





Added sqlplusint/connection2.hh.


































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __connection2_hh__
#define __connection2_hh__

#include "connection1.hh"
#include "query2.hh"

inline Query Connection::query() {return Query(this, throw_exceptions);}

template <class Sequence>
void Connection::storein_sequence (Sequence &seq, const string &str) {
  ResUse result = use(str);
  while (1) {
	  MYSQL_ROW d = mysql_fetch_row(result.mysql_res);
		if (!d) break;
	  Row row(d,&result,true);
		if (!row) break;
    seq.push_back(typename Sequence::value_type(row));
	}
}

template <class Set>
void Connection::storein_set (Set &sett, const string &str) {
  ResUse result = use(str);
	while (1) {
	  MYSQL_ROW d = mysql_fetch_row(result.mysql_res);	
		if (!d) return;
	  Row row(d,&result,true);
		if (!row) break;
    sett.insert(typename Set::value_type(row));
	}
}


#endif
Added sqlplusint/connection3.hh.


1
2
+
+

#include "connection2.hh"
Added sqlplusint/const_string1.hh.



















































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __const_string1_hh__
#define __const_string1_hh__

#include <stdexcept>
#include <string>
#include <iostream>

//: A special string that is created from a existing const char *
// It contains a small subset of the standard string class.  When an
// object is created only a link to the const char * is created.  The
// data is NOT copied.  thus the const char * needs to stick around
// for the life of the class.
class const_string {
private:
  const char *str_data; 
public:
  typedef const char   value_type;      //:
  typedef unsigned int size_type;       //:
  typedef          int difference_type; //:

  typedef const char&     const_reference; //:
  typedef const_reference reference;       //:
  typedef const char*     const_pointer;   //:
  typedef const_pointer   pointer;         //:

  typedef const char*    const_iterator;   //:
  typedef const_iterator iterator;         
  //: The same as const_iterator because the data can not be changed.
  
  const_string() : str_data("") {}                  //:
  const_string(const char *str) : str_data(str) {}  //:
  const_string& operator = (const char *str)        //:
    {str_data = str; return *this;}
 
  size_type size() const //: 
  { register int i = 0;
    while (str_data[i]) i++;
    return i;
  }

  const_iterator  begin() const {return str_data;}          //:
  const_iterator  end()   const {return str_data + size();} //:

  size_type length() const {return size();}   //:
  size_type max_size() const {return size();} //:
  
  const_reference operator[](size_type pos) const {return str_data[pos];} //:
  const_reference at(size_type pos) const //: 
  {
    if (pos >= size()) throw out_of_range("");
    else return str_data[pos];
  }
  
  const char* c_str() const {return str_data;} //:
  const char* data()  const {return str_data;} //:
  
  int compare(const const_string& str) const //:
  {
    const char* str1 = str_data;
    const char* str2 = str.str_data;
    while (*str1 == *str2 && (*str1 || *str2)) {str1++; str2++;}
    return *str1-*str2;
  }
};


//! with_class = const_string

//:
inline ostream& operator << (ostream &o, const const_string &str) {
  return o << str.c_str();
}

//:
inline int compare (const const_string &lhs, const const_string &rhs) {
  return lhs.compare(rhs);
}

//:
inline bool operator == (const_string &lhs, const_string &rhs) {
  return compare(lhs,rhs) == 0;
}

//:
inline bool operator != (const_string &lhs, const_string &rhs) {
  return compare(lhs,rhs) != 0;
}

//:
inline bool operator < (const_string &lhs, const_string &rhs) {
  return compare(lhs,rhs) < 0;
}

//:
inline bool operator <= (const_string &lhs, const_string &rhs) {
  return compare(lhs,rhs) <= 0;
}

//:
inline bool operator > (const_string &lhs, const_string &rhs) {
  return compare(lhs,rhs) > 0;
}

//:
inline bool operator >= (const_string &lhs, const_string &rhs) {
  return compare(lhs,rhs) >= 0;
}

#endif

  
 
  
  
  
Added sqlplusint/const_string2.hh.


1
2
+
+

#include "const_string1.hh"
Added sqlplusint/const_string3.hh.


1
2
+
+

#include "const_string2.hh"
Added sqlplusint/convert1.hh.





















































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __convert1_hh__
#define __convert1_hh__

#include <stdlib.h>

template <class Type> class mysql_convert;

#define mysql__convert(TYPE, FUNC) \
  template <> \
  class mysql_convert<TYPE> {\
  private:\
    TYPE num;\
  public:\
    mysql_convert(const char* str, const char *& end) { \
      num = FUNC(str, const_cast<char **>(&end));}\
    operator TYPE () {return num;}\
  };\

mysql__convert(float, strtod)
mysql__convert(double, strtod)

#undef mysql__convert
#define mysql__convert(TYPE, FUNC) \
  template <> \
  class mysql_convert<TYPE> {\
  private:\
    TYPE num;\
  public:\
    mysql_convert(const char* str, const char *& end) { \
      num = FUNC(str, const_cast<char **>(&end),10);}\
    operator TYPE () {return num;}\
  };\

mysql__convert(char, strtol)
mysql__convert(signed char, strtol)
mysql__convert(int, strtol)
mysql__convert(short int, strtol)
mysql__convert(long int, strtol)

mysql__convert(unsigned char, strtoul)
mysql__convert(unsigned int, strtoul)
mysql__convert(unsigned short int, strtoul)
mysql__convert(unsigned long int, strtoul)

#ifndef NO_LONG_LONGS
mysql__convert(long long int, strtoll)
mysql__convert(unsigned long long int, strtoull)
#endif

#endif



Added sqlplusint/convert2.hh.


1
2
+
+

#include "convert1.hh"
Added sqlplusint/convert3.hh.


1
2
+
+

#include "convert2.hh"
Added sqlplusint/custom.pl.


























































































































































































































































































































































































































































































































































































































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

open (OUT0, ">custom.hh");
open (OUT, ">custom-macros.hh");

print OUT0 << "---";

// This file is generated from the perl script custom.pl, please do 
// not modify this file directly.

#ifndef __sql_custom_h__
#define __sql_custom_h__

enum sql_dummy_type {sql_dummy};
enum sql_cmp_type {sql_use_compare};

inline int sql_cmp(const string &a, const string &b) {
  return a.compare(b);
}
---

@types = ("char", "unsigned char", "tiny_int", "int", "unsigned int",
	  "short int", "unsigned short int");
foreach $type (@types) {
    print OUT0 << "---";

inline int sql_cmp($type a,$type b) {
  return a-b;
}
---
}

@types = ("double", "float");
foreach $type (@types) {
    print OUT0 << "---";

inline int sql_cmp($type a,$type b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}
---
}	

print OUT0 << "---";

#ifndef NO_LONG_LONGS
---

@types = ("long long", "unsigned long long");
foreach $type (@types) {
    print OUT0 << "---";

inline int sql_cmp($type a,$type b) {
  if (a == b) return 0;
  if (a <  b) return -1;
  return 1;
}
---
}	

print OUT0 << "---";

#endif // NO_LONG_LONGS

#include "custom-macros.hh"

#endif

---

print OUT << "---";

// This file is generated from the perl script custom.pl, please do 
// not modify this file directly unless you wish to cut out unnessary
// macros.

// ---------------------------------------------------
//                Begin Mandatory Compare 
// ---------------------------------------------------

#define sql_compare_define(NAME) \\
    bool operator == (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other) == 0;} \\
    bool operator != (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other) != 0;} \\
    bool operator > (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other) >  0;} \\
    bool operator < (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other) <  0;} \\
    bool operator >= (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other) >= 0;} \\
    bool operator <= (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other) <= 0;} \\
    int cmp (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other);} \\
    int compare (const NAME &other) const \\
      {return sql_compare_##NAME##<sql_dummy>(*this,other);}
---

foreach $j (1..26) {
    $parm0 .= "T$j, C$j";
    $parm0 .= ", " unless $j == 26;
    $parm1 .= "C$j";
    $parm1 .= ", " unless $j == 26;
}

print OUT << "---";

#define sql_compare_define_0(NAME, $parm0)

#define sql_construct_define_0(NAME, $parm0)

#define sql_COMPARE__0(NAME, $parm1)

#define sql_compare_type_def_0(NAME, WHAT, NUM) \\
  sql_compare_type_def_##NUM (NAME, WHAT, NUM)

#define sql_compare_type_defe_0(NAME, WHAT, NUM) \\
  sql_compare_type_defe_##NUM (NAME, WHAT, NUM)

// ---------------------------------------------------
//                 End Mandatory Compare 
// ---------------------------------------------------
---

foreach $i (1..26) {
  $compr = ""; $parm2 = ""; $define = "";
  $compr = "    int cmp; \\\n" unless $i == 1;
  $compp = "";
  foreach $j (1..$i) {
      $compr .= "    if (cmp = sql_cmp(x.##C$j , y.##C$j )) return cmp; \\\n"
                                                              unless $j == $i;
      $compr .= "    return sql_cmp(x.##C$j , y.##C$j );"   if $j == $i;
      $parm2 .= "const T$j &p$j";
      $parm2 .= ", "  unless $j == $i;
      $define.= "C$j (p$j)";
      $define.= ", "  unless $j == $i;
      $set   .= "    C$j = p$j;\\\n";
      $compp .= "true";
      $compp .= ", " unless $j == $i;
  }
  print OUT << "---";

// ---------------------------------------------------
//                   Begin Compare $i
// ---------------------------------------------------

#define sql_compare_define_$i(NAME, $parm0) \\
  NAME ($parm2) : $define {} \\
  void set  ($parm2) { \\
$set \\
  } \\
  sql_compare_define(NAME)

#define sql_construct_define_$i(NAME, $parm0) \\
  void set  ($parm2) { \\
$set \\
  } \\
  NAME ($parm2) : $define {}

#define sql_compare_type_def_$i(NAME, WHAT, NUM) \\
  return WHAT##_list(d, m, $compp)

#define sql_compare_type_defe_$i(NAME, WHAT, NUM) \\
  return WHAT##_list(d, c, m, $compp)

#define sql_COMPARE__$i(NAME, $parm1) \\
  template <sql_dummy_type dummy> \\
  int sql_compare_##NAME (const NAME &x, const NAME &y) { \\
$compr \\
  } \\
  template <sql_dummy_type dummy> \\
  int compare (const NAME &x, const NAME &y) { \\
$compr \\
  }

// ---------------------------------------------------
//                   End Compare $i
// ---------------------------------------------------

---
}

print OUT << "---";
---


foreach $i (1..26) {
    $parm_complete = ""; 
    $parm_order = ""; $parm_order2c = "";
    $parm_simple = ""; $parm_simple2c = "";
    $parm_simple_b = ""; $parm_simple2c_b = "";
    $parm_names = ""; $parm_names2c = "";
    $defs = ""; $popul = ""; $parmc = ""; $parmC = "";
    $value_list = ""; $field_list = ""; $equal_list = "";
    $value_list_cus = ""; $cus_field_list = ""; $cus_equal_list = "";
    $create_bool = ""; $create_list = "";
    $cusparms1 = ""; $cusparms2 = ""; $cusparmsv = "";    
    $cusparms11 = ""; $cusparms22 = "";
    $names = "";$enums = "";
    foreach $j (1 .. $i) {
        $parm_complete .= "T$j, I$j, N$j, O$j";
	$parm_complete .= ", " unless $j == $i;
	$parm_order    .= "T$j, I$j, O$j";
	$parm_order    .= ", " unless $j == $i;
        $parm_order2c  .= "T$j, I$j, #I$j, O$j";
	$parm_order2c  .= ", " unless $j == $i;
        $parm_names    .= "T$j, I$j, N$j";
	$parm_names    .= ", " unless $j == $i;
	$parm_names2c  .= "T$j, I$j, N$j, ". ($j-1);
	$parm_names2c  .= ", " unless $j == $i;
	$parm_simple   .= "T$j, I$j";
	$parm_simple   .= ", " unless $j == $i;
	$parm_simple2c .= "T$j, I$j, #I$j, ". ($j-1);
	$parm_simple2c .= ", " unless $j == $i;
	$parm_simple_b   .= "T$j, I$j";
	$parm_simple_b   .= ", " unless $j == $i;
	$parm_simple2c_b .= "T$j, I$j, ". ($j-1);
	$parm_simple2c_b .= ", " unless $j == $i;
	$defs  .= "    T$j I$j;";
	$defs  .= "\n" unless $j == $i;
	$popul .= "    s->##I$j = row[ O$j ];";
	$popul .= "\n" unless $j == $i;
        $names .= "    N$j ";
	$names .= ",\n" unless $j == $i;
        $enums .= "    NAME##_##I$j";
	$enums .= ",\n" unless $j == $i;
        $field_list .= "    s << obj.manip << obj.obj->names[".($j-1)."]";
	$field_list .= " << obj.delem;\n" unless $j == $i;
	$value_list .= "    s << obj.manip << obj.obj->##I$j";
	$value_list .= " << obj.delem;\n" unless $j == $i;
        $create_bool .= "    if (i$j) (*include)[".($j-1)."]=true;\n";
        $create_list .= "    if (i$j == NAME##_NULL) return;\n" unless $i == 1;
        $create_list .= "    (*include)[i$j]=true;\n";

        $value_list_cus .= "    if ((*obj.include)[".($j-1)."]) { \n";
	$value_list_cus .= "      if (before) s << obj.delem;\n" unless $j == 1;
        $value_list_cus .= "      s << obj.manip << obj.obj->##I$j;\n";
	$value_list_cus .= "      before = true; \n" unless $j == $i;
	$value_list_cus .= "     } \n";

        $cus_field_list .= "    if ((*obj.include)[".($j-1)."]) { \n";
	$cus_field_list .= "      if (before) s << obj.delem;\n" unless $j == 1;
        $cus_field_list .= "      s << obj.manip << obj.obj->names[".($j-1)."];\n";
	$cus_field_list .= "      before = true; \n" unless $j == $i;
	$cus_field_list .= "     } \n";

        $cus_equal_list .= "    if ((*obj.include)[".($j-1)."]) { \n";
	$cus_equal_list .= "      if (before) s << obj.delem;\n" unless $j == 1;
        $cus_equal_list .= "      s << obj.obj->names[".($j-1)."] << obj.comp";
        $cus_equal_list .=        " << obj.manip << obj.obj->##I$j;\n";
	$cus_equal_list .= "      before = true; \n" unless $j == $i;
	$cus_equal_list .= "     } \n";

        $equal_list .= "    s << obj.obj->names[".($j-1)."] << obj.comp";
        $equal_list .= " << obj.manip << obj.obj->##I$j";
	$equal_list .= " << obj.delem;\n" unless $j == $i;
        $cusparms1  .= "bool i$j"         if     $j == 1;
	$cusparms1  .= "bool i$j = false" unless $j == 1;
	$cusparms1  .= ", " unless $j == $i;
        $cusparms11  .= "bool i$j" ;
	$cusparms11  .= ", " unless $j == $i;
	$cusparms2  .= "##NAME##_enum i$j" if $j == 1;
	$cusparms2  .= "##NAME##_enum i$j = ##NAME##_NULL" unless $j == 1;
	$cusparms2  .= ", " unless $j == $i;
	$cusparms22  .= "##NAME##_enum i$j";
	$cusparms22  .= ", " unless $j == $i;
        $cusparmsv  .= "i$j";
	$cusparmsv  .= ", " unless $j == $i;
	$parmC .= "T$j, I$j";
	$parmC .= ", " unless $j == 26;
        $parmc .= "I$j";
	$parmc .= ", " unless $j == 26;
    }
    foreach $j ($i+1 .. 26) {
	$parmC .= "0, 0";
	$parmC .= ", " unless $j == 26;
        $parmc .= "0";
	$parmc .= ", " unless $j == 26;
    }

    print OUT << "---";
// ---------------------------------------------------
//                  Begin Create $i
// ---------------------------------------------------
---
    $out = <<"---";
#define sql_create_basic_c_order_$i(NAME, CMP, CONTR, $parm_order)

  struct NAME; 

  template <sql_dummy_type dummy> int sql_compare_##NAME (const NAME &, const NAME &);

  struct NAME { 
$defs 
    NAME () {} 
    NAME (const MysqlRow &row);
    sql_compare_define_##CMP(NAME, $parmC)
  }; 

  template <sql_dummy_type dummy> 
    void populate_##NAME (NAME *s, const MysqlRow &row) { 
$popul 
  } 

  inline NAME##::##NAME (const MysqlRow &row) 
    {populate_##NAME##<sql_dummy>(this, row);} 

  sql_COMPARE__##CMP##(NAME, $parmc )
---
    print OUT &prepare($out);

    $out = <<"---";
#define sql_create_complete_$i(NAME, CMP, CONTR, $parm_complete) 
  struct NAME; 

  enum NAME##_enum { 
$enums 
    ,NAME##_NULL 
  }; 

  template <class Manip>
  class NAME##_value_list { 
  /*friend ostream& operator << <> (ostream&, const NAME##_value_list&); */
  public: 
    const NAME *obj;
    cchar *delem;
    Manip manip;
  public: 
    NAME##_value_list (const NAME *o, cchar *d, Manip m) 
      : obj(o), delem(d), manip(m) {} 
  };

  template <class Manip>
  class NAME##_##field_list {
  /* friend ostream& operator << <> (ostream&, const NAME##_field_list&); */
  public: 
    const NAME *obj; 
    cchar *delem;
    Manip manip;
  public: 
    NAME##_field_list (const NAME *o, cchar *d, Manip m) 
      : obj(o), delem(d), manip(m) {} 
  };

  template <class Manip>
  class NAME##_equal_list { 
  /* friend ostream& operator << <> (ostream&, const NAME##_equal_list&); */
  public: 
    const NAME *obj;
    cchar *delem;
    cchar *comp;
    Manip manip;
  public: 
    NAME##_equal_list (const NAME *o, cchar *d, cchar *c, Manip m) 
      : obj(o), delem(d), comp(c), manip(m) {}
  };

  template <class Manip>
  class NAME##_cus_value_list {
  /* friend ostream& operator << <> (ostream&, 
  				  const NAME##_cus_value_list<Manip>&); */
  public:
    const NAME *obj;
    cchar *delem;
    Manip manip;
    vector<bool> *include;
    bool del_vector;
  public: 
    ~##NAME##_cus_value_list () {if (del_vector) delete include;} 
    NAME##_cus_value_list (const NAME *o, cchar *d, Manip m, $cusparms11);
    NAME##_cus_value_list (const NAME *o, cchar *d, Manip m, $cusparms22); 
    NAME##_cus_value_list (const NAME *o, cchar *d, Manip m ,vector<bool>)
      : obj(o), include(i), del_vector(false), delem(d), manip(m) {}
  };

  template <class Manip>
  class NAME##_cus_field_list { 
  /* friend ostream& operator << <> (ostream&, 
     				  const NAME##_cus_field_list<Manip>&); */
  public:
    const NAME *obj; 
    cchar *delem;
    Manip manip;
    vector<bool> *include; 
    bool del_vector; 
  public: 
    ~##NAME##_cus_field_list () {if (del_vector) delete include;} 
    NAME##_cus_field_list (const NAME *o, cchar *d, Manip m, $cusparms11); 
    NAME##_cus_field_list (const NAME *o, cchar *d, Manip m, $cusparms22); 
    NAME##_cus_field_list (const NAME *o, cchar *d, Manip m, vector<bool> *i) 
      : obj(o), include(i), del_vector(false), delem(d), manip(m) {}
  };

 template <class Manip>
 class NAME##_cus_equal_list {
 /* friend ostream& operator << <> (ostream&, 
				  const NAME##_cus_equal_list<Manip>&); */
  public:
    const NAME *obj;
    vector<bool> *include;
    bool del_vector;
    cchar *delem;
    cchar *comp;
    Manip manip;
  public:
    ~##NAME##_##cus_equal_list () {if (del_vector) delete include;}
    NAME##_##cus_equal_list (const NAME *o, cchar *d, cchar *c, Manip m, $cusparms11); 
    NAME##_##cus_equal_list (const NAME *o, cchar *d, cchar *c, Manip m, $cusparms22); 
    NAME##_##cus_equal_list (const NAME *o, cchar *d, cchar *c, Manip m, vector<bool> *i) 
      : obj(o), include(i), del_vector(false), delem(d), comp(c), manip(m) {}
  };

  template <sql_dummy_type dummy> int sql_compare_##NAME (const NAME &, const NAME &);

  struct NAME { 
$defs 
    NAME () {} 
    NAME (const MysqlRow &row);
    void set (const MysqlRow &row);
    sql_compare_define_##CMP(NAME, $parmC)
    sql_construct_define_##CONTR(NAME, $parmC)
    static char *names[];
    static char *_table;
    static char *& table() {return _table;}

    NAME##_value_list<quote_type0> value_list() const {
      return value_list(",", mysql_quote);}
    NAME##_value_list<quote_type0> value_list(cchar *d) const {
      return value_list(d, mysql_quote);}
    template <class Manip> 
    NAME##_value_list<Manip> value_list(cchar *d, Manip m) const; 

    NAME##_field_list<do_nothing_type0> field_list() const {
      return field_list(",", mysql_do_nothing);}
    NAME##_field_list<do_nothing_type0> field_list(cchar *d) const {
      return field_list(d, mysql_do_nothing);}
    template <class Manip>
    NAME##_field_list<Manip> field_list(cchar *d, Manip m) const; 

    NAME##_equal_list<quote_type0> equal_list(cchar *d = ",", 
                                              cchar *c = " = ") const{
      return equal_list(d, c, mysql_quote);}
    template <class Manip>
    NAME##_equal_list<Manip> equal_list(cchar *d, cchar *c, Manip m) const; 
    
    /* cus_data */

    NAME##_cus_value_list<quote_type0> value_list($cusparms1) const {
      return value_list(",", mysql_quote, $cusparmsv);
    }
    NAME##_cus_value_list<quote_type0> value_list($cusparms2) const {
      return value_list(",", mysql_quote, $cusparmsv);
    }
    NAME##_cus_value_list<quote_type0> value_list(vector<bool> *i) const {
      return value_list(",", mysql_quote, i);
    }
    NAME##_cus_value_list<quote_type0> value_list(sql_cmp_type sc) const {
      return value_list(",", mysql_quote, sc);
    }

    NAME##_cus_value_list<quote_type0> value_list(cchar *d, $cusparms1) const {
      return value_list(d, mysql_quote, $cusparmsv);
    }
    NAME##_cus_value_list<quote_type0> value_list(cchar *d, $cusparms2) const {
      return value_list(d, mysql_quote, $cusparmsv);
    }
    NAME##_cus_value_list<quote_type0> value_list(cchar *d, 
						vector<bool> *i) const {
      return value_list(d, mysql_quote, i);
    }
    NAME##_cus_value_list<quote_type0> value_list(cchar *d, 
						sql_cmp_type sc) const {
      return value_list(d, mysql_quote, sc);
    }

    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(cchar *d, Manip m,
					  $cusparms1) const; 
    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(cchar *d, Manip m,
					  $cusparms2) const; 
    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(cchar *d, Manip m, 
					  vector<bool> *i) const;
    template <class Manip>
    NAME##_cus_value_list<Manip> value_list(cchar *d, Manip m, 
					  sql_cmp_type sc) const;
    /* cus field */

    NAME##_cus_field_list<do_nothing_type0> field_list($cusparms1) const {
      return field_list(",", mysql_do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<do_nothing_type0> field_list($cusparms2) const {
      return field_list(",", mysql_do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<do_nothing_type0> field_list(vector<bool> *i) const {
      return field_list(",", mysql_do_nothing, i);
    }
    NAME##_cus_field_list<do_nothing_type0> field_list(sql_cmp_type sc) const
    {
      return field_list(",", mysql_do_nothing, sc);
    }

    NAME##_cus_field_list<do_nothing_type0> field_list(cchar *d, 
						       $cusparms1) const {
      return field_list(d, mysql_do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<do_nothing_type0> field_list(cchar *d,
						       $cusparms2) const {
      return field_list(d, mysql_do_nothing, $cusparmsv);
    }
    NAME##_cus_field_list<do_nothing_type0> field_list(cchar *d, 
						vector<bool> *i) const {
      return field_list(d, mysql_do_nothing, i);
    }
    NAME##_cus_field_list<do_nothing_type0> field_list(cchar *d, 
						sql_cmp_type sc) const {
      return field_list(d, mysql_do_nothing, sc);
    }

    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(cchar *d, Manip m,
					    $cusparms1) const; 
    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(cchar *d, Manip m,
					    $cusparms2) const; 
    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(cchar *d, Manip m,
					    vector<bool> *i) const;
    template <class Manip>
    NAME##_cus_field_list<Manip> field_list(cchar *d, Manip m, 
					    sql_cmp_type sc) const;

    /* cus equal */

    NAME##_cus_equal_list<quote_type0> equal_list($cusparms1) const {
      return equal_list(",", " = ", mysql_quote, $cusparmsv);
    }
    NAME##_cus_equal_list<quote_type0> equal_list($cusparms2) const {
      return equal_list(",", " = ", mysql_quote, $cusparmsv);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(vector<bool> *i) const {
      return equal_list(",", " = ", mysql_quote, i);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(sql_cmp_type sc) const {
      return equal_list(",", " = ", mysql_quote, sc);
    }

    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, $cusparms1) const {
      return equal_list(d, " = ", mysql_quote, $cusparmsv);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, $cusparms2) const {
      return equal_list(d, " = ", mysql_quote, $cusparmsv);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, 
						vector<bool> *i) const {
      return equal_list(d, " = ", mysql_quote, i);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, 
						sql_cmp_type sc) const {
      return equal_list(d, " = ", mysql_quote, sc);
    }

    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, cchar *c,
                                                $cusparms1) const {
      return equal_list(d, c, mysql_quote, $cusparmsv);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, cchar *c,
                                                $cusparms2) const {
      return equal_list(d, c, mysql_quote, $cusparmsv);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, cchar *c,
						vector<bool> *i) const {
      return equal_list(d, c, mysql_quote, i);
    }
    NAME##_cus_equal_list<quote_type0> equal_list(cchar *d, cchar *c,
						sql_cmp_type sc) const {
      return equal_list(d, c, mysql_quote, sc);
    }

    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(cchar *d, cchar *c, Manip m, 
					    $cusparms1) const; 
    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(cchar *d, cchar *c, Manip m, 
					    $cusparms2) const; 
    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(cchar *d, cchar *c, Manip m, 
					    vector<bool> *i) const;
    template <class Manip>
    NAME##_cus_equal_list<Manip> equal_list(cchar *d, cchar *c, Manip m, 
					    sql_cmp_type sc) const;
  }; 

  char *##NAME##::names[] = { 
$names 
  }; 
  char *##NAME##::_table = #NAME ;  

  template <class Manip>
  NAME##_cus_value_list<Manip>::NAME##_cus_value_list
  (const NAME *o, cchar *d, Manip m, $cusparms11) 
  { 
    delem = d;
    manip = m;
    del_vector = true;
    obj = o; 
    include = new vector<bool>($i, false);
$create_bool 
  } 

  template <class Manip>
  NAME##_cus_value_list<Manip>::NAME##_cus_value_list
  (const NAME *o, cchar *d, Manip m, $cusparms22) { 
    delem = d;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new vector<bool>($i, false); 
$create_list 
  }

  template <class Manip>
  NAME##_cus_field_list<Manip>::NAME##_cus_field_list
  (const NAME *o, cchar *d, Manip m, $cusparms11) {
    delem = d;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new vector<bool>($i, false); 
$create_bool 
  } 

  template <class Manip>
  NAME##_cus_field_list<Manip>::NAME##_cus_field_list
  (const NAME *o, cchar *d, Manip m, $cusparms22) { 
    delem = d;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new vector<bool>($i, false); 
$create_list 
  }

  template <class Manip>
  NAME##_cus_equal_list<Manip>::NAME##_cus_equal_list
  (const NAME *o, cchar *d, cchar *c, Manip m, $cusparms11) { 
    delem = d;
    comp = c;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new vector<bool>($i, false); 
$create_bool 
  } 

  template <class Manip>
  NAME##_cus_equal_list<Manip>::NAME##_cus_equal_list
  (const NAME *o, cchar *d, cchar *c, Manip m, $cusparms22) { 
    delem = d;
    comp = c;
    manip = m;
    del_vector = true; 
    obj = o; 
    include = new vector<bool>($i, false); 
$create_list 
  }

  template <class Manip>
  ostream& operator << (ostream& s, const NAME##_value_list<Manip>& obj) { 
$value_list; 
    return s; 
  } 

  template <class Manip>
  ostream& operator << (ostream& s, const NAME##_field_list<Manip>& obj) { 
$field_list; 
    return s; 
  } 

  template <class Manip>
  ostream& operator << (ostream& s, const NAME##_equal_list<Manip>& obj) { 
$equal_list; 
    return s; 
  } 

  template <class Manip>
  ostream& operator << (ostream& s, const NAME##_cus_value_list<Manip>& obj) { 
    bool before = false; 
$value_list_cus 
    return s; 
  } 

  template <class Manip>
  ostream& operator << (ostream& s, const NAME##_cus_field_list<Manip>& obj) { 
    bool before = false; 
$cus_field_list 
    return s; 
  } 

  template <class Manip>
  ostream& operator << (ostream& s, const NAME##_cus_equal_list<Manip>& obj) { 
    bool before = false; 
$cus_equal_list 
    return s; 
  } 

  template <class Manip>
  inline NAME##_value_list<Manip> NAME##::value_list(cchar *d, Manip m) const { 
    return NAME##_value_list<Manip> (this, d, m); 
  } 

  template <class Manip>
  inline NAME##_field_list<Manip> NAME##::field_list(cchar *d, Manip m) const { 
    return NAME##_field_list<Manip> (this, d, m); 
  } 

  template <class Manip>
  inline NAME##_equal_list<Manip> NAME##::equal_list(cchar *d, cchar *c, Manip m) const { 
    return NAME##_equal_list<Manip> (this, d, c, m); 
  } 
 
  template <class Manip>
  inline NAME##_cus_value_list<Manip> NAME##::value_list(cchar *d, Manip m,
						       $cusparms11) const {
    return NAME##_cus_value_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_field_list<Manip> NAME##::field_list(cchar *d, Manip m,
							 $cusparms11) const { 
    return NAME##_cus_field_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> NAME##::equal_list(cchar *d, cchar *c, Manip m,
							 $cusparms11) const { 
    return NAME##_cus_equal_list<Manip> (this, d, c, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_value_list<Manip> NAME##::value_list(cchar *d, Manip m,
						       $cusparms22) const { 
    return NAME##_cus_value_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_field_list<Manip> NAME##::field_list(cchar *d, Manip m,
							 $cusparms22) const {
    return NAME##_cus_field_list<Manip> (this, d, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> NAME##::equal_list(cchar *d, cchar *c, Manip m, 
							 $cusparms22) const { 
    return NAME##_cus_equal_list<Manip> (this, d, c, m, $cusparmsv); 
  } 

  template <class Manip>
  inline NAME##_cus_value_list<Manip> 
  NAME##::value_list(cchar *d, Manip m, sql_cmp_type sc) const {
    sql_compare_type_def_##CMP (NAME, value, NUM);
  }

  template <class Manip>
  inline NAME##_cus_field_list<Manip> 
  NAME##::field_list(cchar *d, Manip m, sql_cmp_type sc) const {
    sql_compare_type_def_##CMP (NAME, field, NUM);
  }

  template <class Manip>
  inline NAME##_cus_equal_list<Manip> 
  NAME##::equal_list(cchar *d, cchar *c, Manip m, sql_cmp_type sc) const {
    sql_compare_type_defe_##CMP (NAME, equal, NUM);
  }

  template <sql_dummy_type dummy> 
  void populate_##NAME (NAME *s, const MysqlRow &row) { 
$popul
  } 

  inline NAME##::##NAME (const MysqlRow &row) 
                                        {populate_##NAME##<sql_dummy>(this, row);}
  inline void NAME##::set (const MysqlRow &row)
                                        {populate_##NAME##<sql_dummy>(this, row);}

  sql_COMPARE__##CMP##(NAME, $parmc )
---
print OUT &prepare($out);

#
# short cut defs
#

print OUT << "---";
#define sql_create_basic_$i(NAME, CMP, CONTR, $parm_simple_b) \\
  sql_create_basic_c_order_$i(NAME, CMP, CONTR, $parm_simple2c_b)

#define sql_create_$i(NAME, CMP, CONTR, $parm_simple) \\
  sql_create_complete_$i(NAME, CMP, CONTR, $parm_simple2c) \\

#define sql_create_c_order_$i(NAME, CMP, CONTR, $parm_order) \\
  sql_create_complete_$i(NAME, CMP, CONTR, $parm_order2c)

#define sql_create_c_names_$i(NAME, CMP, CONTR, $parm_names) \\
  sql_create_complete_$i(NAME, CMP, CONTR, $parm_names2c)

// ---------------------------------------------------
//                  End Create $i
// ---------------------------------------------------

---

}


sub prepare {
    local $_ = @_[0];
    s/\n+$//;
    s/\n[\n ]*\n/\n/g; 
    s/\n+/\\\n/g;
    $_ .= "\n\n";
    return $_;
}

Added sqlplusint/datetime.cc.
































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include "datetime3.hh"
#include <iomanip.h>

ostream& mysql_date::out_stream (ostream& s) const {
  char fill = s.fill('0');
#ifdef __USLC__
  long flags = s.setf(ios::right);
#else
  ios::fmtflags flags = s.setf(ios::right);
#endif
  s << setw(4) << year << '-' 
    << setw(2) << month << '-'
    << setw(2) << day;
  s.flags(flags);
  s.fill(fill);
  return s;
}

ostream& mysql_time::out_stream (ostream& s) const {
  char fill = s.fill('0');
#ifdef __USLC__
  long flags = s.setf(ios::right);
#else
  ios::fmtflags flags = s.setf(ios::right);
#endif
  s << setw(2) << hour << ':' 
    << setw(2) << minute << ':'
    << setw(2) << second;
  s.flags(flags);
  s.fill(fill);
  return s;
}

ostream& MysqlDateTime::out_stream (ostream& s) const {
  mysql_date::out_stream(s);
  s << " ";
  mysql_time::out_stream(s);
  return s;
}

cchar* mysql_date::convert (cchar* str) {
  char num[5];
  num[0] =*str++; num[1] =*str++; num[2] =*str++; num[3] =*str++; num[4] = 0;
  year = strtol(num,0,10);
  if (*str == '-') str++;
  num[0] = *str++; num[1] = *str++; num[2] = 0;
  month = strtol(num,0,10);
  if (*str == '-') str++;
  num[0] = *str++; num[1] = *str++; num[2] = 0;
  day = strtol(num,0,10);
  return str;
}

cchar* mysql_time::convert (cchar* str) {
  char num[5];
  num[0] = *str++; num[1] = *str++; num[2] = 0;
  hour = strtol(num,0,10);
  if (*str == ':') str++;
  num[0] = *str++; num[1] = *str++; num[2] = 0;
  minute = strtol(num,0,10);
  if (*str == ':') str++;
  num[0] = *str++; num[1] = *str++; num[2] = 0;
  second = strtol(num,0,10);
  return str;
}

cchar* MysqlDateTime::convert (cchar* str) {
  str = mysql_date::convert(str);
  if (*str == ' ') str++;
  str = mysql_time::convert(str);
  return str;
}

short int mysql_date::compare(const mysql_date* other) const {
  if (year != other->year) return year - other->year;
  if (month != other->month) return month - other->month;
  return day - other->day;
}

short int mysql_time::compare(const mysql_time* other) const {
  if (hour != other->hour) return hour - other->hour;
  if (minute != other->minute) return minute - other->minute;
  return minute - other->minute;
}

short int MysqlDateTime::compare(const MysqlDateTime &other) const {
  int x;
  x = mysql_date::compare(&other);
  if (x) return x;
  return mysql_time::compare(&other);
}





Added sqlplusint/datetime1.hh.























































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __datatime1_hh__

#ifndef __datetime1_hh__

// for some strange strange reason when I just use one #ifndef it
// doesn't work.  If anyone has any idea what is going on please let
// me know

#define __datetime1_hh__

#include <string>
#include <strstream.h>
#include <iostream.h>
#include "defs"
#include "define_short"
#include "coldata1.hh"
#include "stream2string1.hh"
#include "tiny_int1.hh"

struct mysql_dt_base {
  virtual ostream& out_stream(ostream&) const = 0;

  operator string ();
};

template <class T>
struct MysqlDTbase {
  virtual short int compare(const T &other) const = 0;

  bool operator == (const T &other) const {return !compare(other);}
  bool operator != (const T &other) const {return compare(other);}
  bool operator <  (const T &other) const {return compare(other) < 0;}
  bool operator <= (const T &other) const {return compare(other) <= 0;}
  bool operator >  (const T &other) const {return compare(other) > 0;}
  bool operator >= (const T &other) const {return compare(other) >= 0;}
};

struct mysql_date : virtual public mysql_dt_base {
  short int year;
  tiny_int  month;
  tiny_int  day;

  ostream& out_stream(ostream&) const;
  cchar* convert (cchar*);
protected:
  short int compare(const mysql_date *other) const;
};

//: A special type for holding mysql Dates.
// Date, a comparable data structures for holding mysql Dates.  It also
// responds to the stream extraction and insertion operator.
/*!dummy:
  struct Date {
    short int year;  //: The year in 4 digit form
    tiny_int  month; //: The month number
    tiny_int  day;   //: The day of the month

    Date ();                    //:
    Date (cchar* str);          //:
    Date (const ColData &str);  //:
    Date (const string &str);   //:

    short int compare(const Date& other) const;
    //: Compare two dates
    // Returns 0 if *this == other, <0 if *this < *other, >0 if *this > other
  };
*/

struct Date : public mysql_date, public MysqlDTbase<Date>
{
  Date () {};
  Date (cchar* str) {convert(str);}
  Date (const ColData &str);
  Date (const string &str);

  short int compare(const Date& other) const 
    {return mysql_date::compare(&other);}
};

inline ostream& operator << (ostream& s, const Date& d) 
                                                  {return d.out_stream(s);}

struct mysql_time : virtual public mysql_dt_base {
  tiny_int hour;
  tiny_int minute;  
  tiny_int second;

  ostream& out_stream(ostream&) const;
  cchar* convert (cchar*);
protected:
  short int compare(const mysql_time *other) const;
};  

//: A special type for holding mysql Dates.
// Time, a comparable data structures for holding mysql Times.  It also
// responds to the stream extraction and insertion operator.
/*!dummy:
  struct Time {
    tiny_int hour;   //: Hour in military time
    tiny_int minute; //:
    tiny_int second; //:

    Time () {};                //:
    Time (cchar* str);         //:
    Time (const ColData &str); //:
    Time (const string &str);  //:

    short int compare(const Time& other) const;
    //: Compare two times
    // Returns 0 if *this == other, <0 if *this < *other, >0 if *this > other
  };
*/

struct Time : public mysql_time, public MysqlDTbase<Time>
{
  Time () {};
  Time (cchar* str) {convert(str);}
  Time (const ColData &str);
  Time (const string &str);

  short int compare(const Time& other) const 
    {return mysql_time::compare(&other);}
};


inline ostream& operator << (ostream& s, const Time& d)
                                                 {return d.out_stream(s);}

//: A combinate of Date and Time for holding mysql DateTime's
//!dummy: struct DateTime {};

struct DateTime : public mysql_date, public mysql_time,
		       public MysqlDTbase<DateTime>
{
  DateTime () {}
  DateTime (cchar* str) {convert(str);}
  DateTime (const ColData &str);
  DateTime (const string &str);

  short int compare(const DateTime& other) const;

  ostream& out_stream(ostream&) const;
  cchar* convert (cchar*);
};

inline ostream& operator << (ostream& s, const DateTime& d)
                                                   {return d.out_stream(s);}

#endif
#endif //__datetime1_hh__

Added sqlplusint/datetime2.hh.





















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __datetime2_hh__
#define __datetime2_hh__

#include "datetime1.hh"
#include "coldata2.hh"
#include "stream2string2.hh"

inline mysql_dt_base::operator string () {
  return stream2string<string>(*this);
}

inline Date::Date (const ColData &str) {convert(str.c_str());}
inline Date::Date (const string &str)  {convert(str.c_str());}

inline Time::Time (const ColData &str) {convert(str.c_str());}
inline Time::Time (const string &str)  {convert(str.c_str());}

inline DateTime::DateTime (const ColData &str) {convert(str.c_str());}
inline DateTime::DateTime (const string &str) {convert(str.c_str());}

#endif
Added sqlplusint/datetime3.hh.



1
2
3
+
+
+

#include "datetime2.hh"

Added sqlplusint/define_short.
































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

// defs.h

#ifndef __define_short_h__
#define __define_short_h__

#define use_exceptions mysql_use_exceptions

// base.h           
#define BadQuery    MysqlBadQuery
#define MysqlCon    MysqlConnection
#define Connection  MysqlConnection

// result.h
#define ResNSel     MysqlResNSel
#define ResUse      MysqlResUse
#define Result      MysqlRes
#define Field       MysqlField
#define Fields      MysqlFields

// resiter.h
#define ResIter     MysqlResIter
#define ResultIter  MysqlResIter

// row.h
#define Row          MysqlRow
#define MutableRow   MysqlMutableRow

// field_names.h
#define FieldNames  MysqlFieldNames

//query.h
#define Query       MysqlQuery

//string.h
#define BadConversion  MysqlBadConversion
#define ColData        MysqlColData
#define MutableColData MysqlMutableColData

// manip.h
#define quote              mysql_quote
#define quote_only         mysql_quote_only
#define quote_double_only  mysql_quote_double_only
#define escape             mysql_escape
#define do_nothing         mysql_do_nothing
#define ignore             mysql_ignore

// datetime.h
#define Date        MysqlDate
#define Time        MysqlTime
#define DateTime    MysqlDateTime

// set.h
#define Set         MysqlSet

// null.h
#define Null        MysqlNull
#define null_type   mysql_null_type
#define null        mysql_null
#define NullisNull  MysqlNullisNull
#define NullisZero  MysqlNullisZero
#define NullisBlank MysqlNullisBlank

#endif
Added sqlplusint/defs.




















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#ifndef __mysql_defs_h_
#define __mysql_defs_h_

#include <mysql.h>
#include "define_short"

typedef MYSQL_FIELD MysqlField;
typedef const char cchar;
typedef long long int longgint;

class Connection;
class ResUse;
class Result;
class FieldNames;

const bool use_exceptions = true;

#endif

Added sqlplusint/field_names.cc.












1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+
+
+
+
+
+
+
+

#include "field_names3.hh"
#include "result2.hh"

void FieldNames::init(const ResUse *res) {
  int num = res->num_fields();
  reserve(num);
  for (int i = 0; i < num; i++) {
    push_back(res->fields()[i].name);
  }
}

Added sqlplusint/field_names1.hh.






































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#ifndef __field_names1_hh__
#define __field_names1_hh__

#include <vector.h>
#include <algo.h>
#include "defs"
#include "define_short"
#include "coldata1.hh"

//: A vector of the field names.
class FieldNames : public vector<string> {
private:
  void init (const ResUse *res);
public:
  FieldNames () {}
  FieldNames (const ResUse *res) {init(res);}
  FieldNames (int i) : vector<string>(i) {}

  FieldNames& operator = (const ResUse *res) {init(res); return *this;}  
  //: Creates a new list from the data in res.
  FieldNames& operator = (int i) {insert(begin(), i, ""); return *this;} 
  //: Creates a new list with i field names.
  
  string&  operator [] (int i) {return vector<string>::operator [] (i);}
  //: returns the field name of the field with that index number

  const string&  operator [] (int i) const 
    {return vector<string>::operator [] (i);}
  //: returns the field name of the field with that index number

  uint     operator [] (string i) const
    {return find(begin(),end(), i) - begin();}
  //: returns the index number of the field with that name
};

#endif

Added sqlplusint/field_names2.hh.


1
2
+
+

#include "field_names1.hh"
Added sqlplusint/field_names3.hh.


1
2
+
+

#include "field_names2.hh"
Added sqlplusint/field_types.cc.












1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+
+
+
+
+
+
+
+

#include "field_types3.hh"
#include "result2.hh"

void FieldTypes::init(const ResUse *res) {
  int num = res->num_fields();
  reserve(num);
  for (int i = 0; i < num; i++) {
    push_back(res->fields(i));
  }
}

Added sqlplusint/field_types1.hh.





































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __field_types1_hh__
#define __field_types1_hh__

#include <vector.h>
#include "defs"
#include "define_short"
#include "type_info1.hh"

//: A vector of the field types.
class FieldTypes : public vector<mysql_type_info> {
private:
  void init (const ResUse *res);
public:
  FieldTypes () {}
  FieldTypes (const ResUse *res) {init(res);}
  FieldTypes (int i) : vector<mysql_type_info>(i) {}

  FieldTypes& operator = (const ResUse *res) {init(res); return *this;}
  //: Creates a new list based on the info in res
  FieldTypes& operator = (int i) {insert(begin(), i, 
					 mysql_type_info()); return *this;}
  //: Creates a new list with i fields. 
  
  mysql_type_info&  operator [] (int i) {return vector<mysql_type_info>
				  ::operator [] (i);}
  //: Returns the field type for the field with an offset of i.
  const mysql_type_info&  operator [] (int i) const 
    {return vector<mysql_type_info>::operator[] (i);}
  //: Returns the field type for the field with an offset of i.
};

#endif





Added sqlplusint/field_types2.hh.


1
2
+
+

#include "field_types1.hh"
Added sqlplusint/field_types3.hh.


1
2
+
+

#include "field_types2.hh"
Added sqlplusint/fields1.hh.























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __fields1_hh__
#define __fields1_hh__

#include "resiter1.hh"

class ResUse;

//: A vector like container with the raw mysql field info.
class Fields : public const_subscript_container<Fields, Field>
{
private:
  mutable ResUse *res;
public:
  Fields() {}
  Fields(ResUse *r) : res(r) {}
  size_type size() const; //: the number of fields.
  //: Returns the field with an offset of i;
  const Field& operator [] (size_type i) const;
  const Field& operator [] (int i) const {return operator [](size_type(i));} 
};

#endif

Added sqlplusint/fields2.hh.












1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+
+
+
+
+
+
+
+

#ifndef __fields2_hh__
#define __fields2_hh__

inline Fields::size_type Fields::size() const {return res->num_fields();}

inline const Field& Fields::operator [] (Fields::size_type i) const {
    res->field_seek(i); 
    return res->fetch_field();
}

#endif
Added sqlplusint/magic.h.



































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#define virtual_def (oper) \
  virtual operator oper () const = 0; \
  virtual holder* create(const &oper) = 0

#define virtual_int_def (oper) \
  virtual_def (oper); \
  vortual_def (unsigned oper)


class MagicType {
  class holder_base {
  public:
    virtual_int_def (char);
    virtual_int_def (short int);
    virtual_int_def (long ing);
    virtual_int_def (long long int);
    virtual_def (float);
    virtual_def (double);
    virtual_def (string);
  }
  template <class Type, const char* Name, tiny_int Id, unsigned short int Id2,
            unsigned short int Mask>
  class holder : public holder_base {
  public:
    Type value;
    static const name = Name;
    static const tiny_int id = Id;
    static const unsigned short int id2 = Id2;
    static const unsigned short int mask = Mask;
  }

    
  
      
    
Added sqlplusint/manip.cc.

















































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "manip3.hh"

// quote manipulator

SQLQueryParms& operator << (quote_type2 p, SQLString &in) {
  if (in.is_string) {
    if (in.dont_escape) {
      SQLString in2 = "'" + in + "'";
      in2.processed = true;
      return *p.qparms << in2;
    } else {
      char* s = new char[in.size()*2+1];
      mysql_escape_string(s, const_cast<char *>(in.c_str()), in.size() );
      SQLString in2 = SQLString("'") + s + "'";
      in2.processed = true;
      *p.qparms << in2;
      delete s;
      return *p.qparms;
    }
  } else {
    in.processed = true;
    return *p.qparms << in;
  }
}

template <>
ostream& operator << (quote_type1 o, const string &in) {
  char* s = new char[in.size()*2+1];
  mysql_escape_string(s, const_cast<char *>(in.c_str()), in.size() );
  *o.ostr << "'" << s << "'";
  delete s;
  return *o.ostr;
}

template <>
ostream& operator << (quote_type1 o, const char* const &in) {
  unsigned int size;
  for (size=0; in[size]; size++);
  char* s = new char[size*2];
  mysql_escape_string(s, const_cast<char *>(in), size);
  *o.ostr << "'" << s << "'";
  delete s; 
  return *o.ostr;
}

template <class Str>
inline ostream& _manip (quote_type1 o, const mysql_ColData<Str>& in) {
  if (in.escape_q()) {
    char *s = new char[in.size()*2+1];
    mysql_escape_string(s, const_cast<char *>(in.c_str()), in.size() );
    if (in.quote_q())
      *o.ostr << "'" << s << "'";
    else
      *o.ostr << s;
    delete s;
  } else if (in.quote_q()) {
    *o.ostr << "'" << in << "'";
  } else {
    *o.ostr << in;
  }
  return *o.ostr;
}

template <>
ostream& operator << (quote_type1 o, const mysql_ColData<string>& in) {
  return _manip(o,in);
}

template <>
ostream& operator << (quote_type1 o, const mysql_ColData<const_string>& in) {
  return _manip(o,in);
}

// quote only manipulator

SQLQueryParms & operator << (quote_only_type2 p, SQLString &in) {
  if (in.is_string) {
    SQLString in2 = "'" + in + "'";
    in2.processed = true;
    return *p.qparms << in2;
  } else {
    in.processed = true;
    return *p.qparms << in;
  }
}

template <>
ostream& operator << (quote_only_type1 o, const mysql_ColData<string>& in) {
  if (in.quote_q()) {
    *o.ostr << "'" << in << "'";
  } else {
    *o.ostr << in;
  }
  return *o.ostr;
}

template <>
ostream& operator << (quote_only_type1 o, const mysql_ColData<const_string>& in) {
  if (in.quote_q()) {
    *o.ostr << "'" << in << "'";
  } else {
    *o.ostr << in;
  }
  return *o.ostr;
}

// quote double only manipulator

SQLQueryParms & operator << (quote_double_only_type2 p, SQLString &in) {
  if (in.is_string) {
    SQLString in2 = "\"" + in + "\"";
    in2.processed = true;
    return *p.qparms << in2;
  } else {
    in.processed = true;
    return *p.qparms << in;
  }
}


template <>
ostream& operator << (quote_double_only_type1 o, const mysql_ColData<string>& in) {
  if (in.quote_q()) {
    *o.ostr << "'" << in << "'";
  } else {
    *o.ostr << in;
  }
  return *o.ostr;
}

template <>
ostream& operator << (quote_double_only_type1 o, const mysql_ColData<const_string>& in) {
  if (in.quote_q()) {
    *o.ostr << "'" << in << "'";
  } else {
    *o.ostr << in;
  }
  return *o.ostr;
}

// escape manipulator

SQLQueryParms & operator << (escape_type2 p, SQLString &in) {
  if (in.is_string) {
    if (in.dont_escape) {
      in.processed = true;
      return *p.qparms << in;
    } else {
      char* s = new char[in.size()*2+1];
      mysql_escape_string(s, const_cast<char *>(in.c_str()), in.size() );
      SQLString in2 = s;
      in2.processed = true;
      *p.qparms << in2;
      delete s;
      return *p.qparms;
    }
  } else {
    in.processed = true;
    return *p.qparms << in;
  }
}

template <>
ostream& operator << (escape_type1 o, const string &in) {
  char* s = new char[in.size()*2+1];
  mysql_escape_string(s, const_cast<char *>(in.c_str()), in.size());
  *o.ostr << s;
  delete s;
  return *o.ostr;
}

template <>
ostream& operator << (escape_type1 o, const char* const &in) {
  unsigned int size;
  for (size=0; in[size]; size++);
  char* s = new char[size*2];
  mysql_escape_string(s, const_cast<char *>(in), size);
  *o.ostr << s;
  delete s; 
  return *o.ostr;
}


template <class Str>
inline ostream& _manip (escape_type1 o, const mysql_ColData<Str>& in) {
  if (in.escape_q()) {
    char *s = new char[in.size()*2+1];
    mysql_escape_string(s, const_cast<char *>(in.c_str()), in.size() );
    delete s;
  } else {
    *o.ostr << in;
  }
  return *o.ostr;
}

template <>
ostream& operator << (escape_type1 o, const mysql_ColData<string>& in) {
  return _manip(o,in);
}

template <>
ostream& operator << (escape_type1 o, const mysql_ColData<const_string>& in) {
  return _manip(o,in);
}




Added sqlplusint/manip1.hh.


















































































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __manip1_hh__
#define __manip1_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <mysql.h>
#include <iostream>
#include "define_short"
#include "sql_string1.hh"
#include "sql_query1.hh"
#include "datetime1.hh"
#include "set1.hh"

//quote manipulaor

class SQLQueryParms;

enum quote_type0 {mysql_quote};

struct quote_type1 {
  ostream *ostr;
  quote_type1(ostream *o) : ostr(o) {}
}; 

inline quote_type1 operator << (ostream &o, quote_type0 esc) {
  return quote_type1(&o);
}

struct quote_type2 {
  SQLQueryParms *qparms;
  quote_type2(SQLQueryParms *p) : qparms(p) {}
};

inline quote_type2 operator << (SQLQueryParms &p, quote_type0 esc) {
  return quote_type2(&p);
}

SQLQueryParms& operator << (quote_type2 p, SQLString &in);

template <class T>
inline ostream& operator << (quote_type1 o, const T &in) {
  return *o.ostr << in;
}

template <>
ostream& operator << (quote_type1 o, const string &in);

template <>
ostream& operator << (quote_type1 o, const char* const &in);

template <>
ostream& operator << (quote_type1 o, const mysql_ColData<string>& in);

template <>
ostream& operator << (quote_type1 o, const mysql_ColData<const_string>& in);

template <>
inline ostream& operator << (quote_type1 o, char* const &in) {
  return operator << (o, const_cast<const char* const &>(in));
}

template <>
inline ostream& operator << (quote_type1 o, const Date &in) {
  return *o.ostr << "'" << in << "'";
}

template <>
inline ostream& operator << (quote_type1 o, const Time &in) {
  return *o.ostr << "'" << in << "'";
}

template <>
inline ostream& operator << (quote_type1 o, const DateTime &in) {
  return *o.ostr << "'" << in << "'";
}

template <class ST>
inline ostream& operator << (quote_type1 o, const MysqlSet<ST> &in) {
  return *o.ostr << "'" << in << "'";
}

// quote only manipulator

enum quote_only_type0 {mysql_quote_only};

struct quote_only_type1 {
  ostream *ostr;
  quote_only_type1(ostream *o) : ostr(o) {}
}; 

inline quote_only_type1 operator << (ostream &o, quote_only_type0 esc) {
  return quote_only_type1(&o);
}

struct quote_only_type2 {
  SQLQueryParms *qparms;
  quote_only_type2(SQLQueryParms *p) : qparms(p) {}
};

inline quote_only_type2 operator << (SQLQueryParms &p, quote_only_type0 esc) {
  return quote_only_type2(&p);
}

SQLQueryParms & operator << (quote_only_type2 p, SQLString &in);

template <class T>
inline ostream& operator << (quote_only_type1 o, const T &in) {
  return *o.ostr << in;
}

template <>
inline ostream& operator << (quote_only_type1 o, const string &in) {
  return *o.ostr << "'" << in << "'";
}

template <>
ostream& operator << (quote_only_type1 o, const mysql_ColData<string>& in);

template <>
ostream& operator << (quote_only_type1 o, const mysql_ColData<const_string>& in);

template <>
inline ostream& operator << (quote_only_type1 o, const Date &in) {
  return *o.ostr << "'" << in << "'";
}

template <>
inline ostream& operator << (quote_only_type1 o, const Time &in) {
  return *o.ostr << "'" << in << "'";
}

template <>
inline ostream& operator << (quote_only_type1 o, const DateTime &in) {
  return *o.ostr << "'" << in << "'";
}

template <class ST>
inline ostream& operator << (quote_only_type1 o, const MysqlSet<ST> &in) {
  return *o.ostr << "'" << in << "'";
}

// quote double (") only manipulator

enum quote_double_only_type0 {mysql_quote_double_only};
struct quote_double_only_type1 {
  ostream *ostr;
  quote_double_only_type1(ostream *o) : ostr(o) {}
}; 

inline quote_double_only_type1 operator << (ostream &o, 
					    quote_double_only_type0 esc) {
  return quote_double_only_type1(&o);
}

struct quote_double_only_type2 {
  SQLQueryParms *qparms;
  quote_double_only_type2(SQLQueryParms *p) : qparms(p) {}
};

inline quote_double_only_type2 operator << (SQLQueryParms &p, 
					     quote_double_only_type0 esc) {
  return quote_double_only_type2(&p);
}

SQLQueryParms & operator << (quote_double_only_type2 p, SQLString &in);

template <class T>
inline ostream& operator << (quote_double_only_type1 o, const T &in) {
  return *o.ostr << in;
}

template <>
inline ostream& operator << (quote_double_only_type1 o, const string &in) {
  return *o.ostr << "\"" << in << "\"";
}

template <>
ostream& operator << (quote_double_only_type1 o, const mysql_ColData<string>& in);

template <>
ostream& operator << (quote_double_only_type1 o, const mysql_ColData<const_string>& in);

template <>
inline ostream& operator << (quote_double_only_type1 o, const Date &in) {
  return *o.ostr << "\"" << in << "\"";
}

template <>
inline ostream& operator << (quote_double_only_type1 o, const Time &in) {
  return *o.ostr << "\"" << in << "\"";
}

template <>
inline ostream& operator << (quote_double_only_type1 o, 
			     const DateTime &in) {
  return *o.ostr << "\"" << in << "\"";
}

template <class ST>
inline ostream& operator << (quote_double_only_type1 o, 
			     const MysqlSet<ST> &in) {
  return *o.ostr << "\"" << in << "\"";
}

// escape manipulator

enum escape_type0 {mysql_escape};
struct escape_type1 {
  ostream *ostr;
  escape_type1(ostream *o) : ostr(o) {}
}; 

inline escape_type1 operator << (ostream &o, escape_type0 esc) {
  return escape_type1(&o);
}

struct escape_type2 {
  SQLQueryParms *qparms;
  escape_type2(SQLQueryParms *p) : qparms(p) {}
};

inline escape_type2 operator << (SQLQueryParms &p, escape_type0 esc) {
  return escape_type2(&p);
}

SQLQueryParms & operator << (escape_type2 p, SQLString &in);

template <class T>
inline ostream& operator << (escape_type1 o, const T &in) {
  return *o.ostr << in;
}

template <>
ostream& operator << (escape_type1 o, const string &in);

template <>
ostream& operator << (escape_type1 o, const char* const &in);

template <>
ostream& operator << (escape_type1 o, const mysql_ColData<string>& in);

template <>
ostream& operator << (escape_type1 o, const mysql_ColData<const_string>& in);

template <>
inline ostream& operator << (escape_type1 o, char* const &in) {
  return operator << (o, const_cast<const char* const &>(in));
}


//do nothing manipulator

enum do_nothing_type0 {mysql_do_nothing};
struct do_nothing_type1 {
  ostream *ostr;
  do_nothing_type1(ostream *o) : ostr(o) {}
}; 

inline do_nothing_type1 operator << (ostream &o, do_nothing_type0 esc) {
  return do_nothing_type1(&o);
}

template <class T>
inline ostream& operator << (do_nothing_type1 o, const T &in) {
  return *o.ostr << in;
}

struct do_nothing_type2 {
  SQLQueryParms *qparms;
  do_nothing_type2(SQLQueryParms *p) : qparms(p) {}
};

inline do_nothing_type2 operator << (SQLQueryParms &p, do_nothing_type0 esc) {
  return do_nothing_type2(&p);
}

inline SQLQueryParms & operator << (do_nothing_type2 p, SQLString &in) {
  in.processed = true;
  return *p.qparms << in;
}

enum ignore_type0 {mysql_ignore};

struct ignore_type2 {
  SQLQueryParms *qparms;
  ignore_type2(SQLQueryParms *p) : qparms(p) {}
};

inline ignore_type2 operator << (SQLQueryParms &p, ignore_type0 esc) {
  return ignore_type2(&p);
}

inline SQLQueryParms & operator << (ignore_type2 p, SQLString &in) {
  return *p.qparms << in;
}

#endif





Added sqlplusint/manip2.hh.


1
2
+
+

#include "manip1.hh"
Added sqlplusint/manip3.hh.


1
2
+
+

#include "manip2.hh"
Added sqlplusint/mysql++.









































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "defs"
#include "define_short"

#include "coldata1.hh"
#include "compare1.hh"
#include "connection1.hh"
#include "const_string1.hh"
#include "convert1.hh"
#include "datetime1.hh"
#include "field_names1.hh"
#include "field_types1.hh"
#include "fields1.hh"
#include "manip1.hh"
#include "null1.hh"
#include "query1.hh"
#include "resiter1.hh"
#include "result1.hh"
#include "row1.hh"
#include "set1.hh"
#include "sql_query1.hh"
#include "sql_string1.hh"
#include "stream2string1.hh"
#include "tiny_int1.hh"
#include "type_info1.hh"
#include "vallist1.hh"

#include "coldata2.hh"
#include "compare2.hh"
#include "connection2.hh"
#include "const_string2.hh"
#include "convert2.hh"
#include "datetime2.hh"
#include "field_names2.hh"
#include "field_types2.hh"
#include "fields2.hh"
#include "manip2.hh"
#include "null2.hh"
#include "query2.hh"
#include "result2.hh"
#include "row2.hh"
#include "set2.hh"
#include "sql_query2.hh"
#include "sql_string2.hh"
#include "stream2string2.hh"
#include "tiny_int2.hh"
#include "type_info2.hh"
#include "vallist2.hh"

#include "coldata3.hh"
#include "compare3.hh"
#include "connection3.hh"
#include "const_string3.hh"
#include "convert3.hh"
#include "datetime3.hh"
#include "field_names3.hh"
#include "field_types3.hh"
#include "manip3.hh"
#include "null3.hh"
#include "query3.hh"
#include "result3.hh"
#include "row3.hh"
#include "set3.hh"
#include "sql_query3.hh"
#include "sql_string3.hh"
#include "stream2string3.hh"
#include "tiny_int3.hh"
#include "type_info3.hh"
#include "vallist3.hh"

#ifdef MYSQL_NO_SHORT_NAMES
#include "undef_short"
#endif
Added sqlplusint/null1.hh.

















































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __null1_hh__
#define __null1_hh__

#include <ostream.h>
#include "define_short"

//! with_class = Null

//: Thrown when a *Null* value is trying to be converted into a type 
//: it can't convert to.
class BadNullConversion {};

class null_type {
public:
  template <class Type> operator Type () {throw BadNullConversion();}
};

//: 
const null_type null = null_type();

//: Type to use for the behavior parameter for *Null<>*
struct NullisNull {
  static null_type null_is() {return null_type();}
  static ostream&  null_ostr(ostream& o) {o << "(NULL)"; return o;}
};

//: Type to use for the behavior parameter for *Null<>*
struct NullisZero {
  static int   null_is() {return 0;}
  static ostream& null_ostr(ostream &o) {o << 0; return o;}
};

//: Type to use for the behavior parameter for *Null<>*
struct NullisBlank {
  static const char * null_is() {return "";}
  static ostream& null_ostr(ostream &o) {o << ""; return o;}
};

//: Container class for holding null types.
template <class Type, class Behavior = NullisNull>
class Null {
public:
  Type data;
  bool is_null;
  typedef Type value_type;
public:
  Null () {} //:
  Null (Type x) : data(x), is_null(false) {} 
  //: 
  Null (const null_type &n) : is_null(true) {} 
  //: Gives Null the null value
  // Note: the global const *null* (not NULL) is of value null_type thus 
  // you can say something like *Null<Type> x = null*.
  operator Type& () { 
    if (is_null) return data = Behavior::null_is();
    else return data; } 
  //:
  Null& operator = (const Type &x) {data = x; is_null = false; return *this;}
  //: 
  Null& operator = (const null_type &n) {is_null = true; return *this;}
  //:
};

//: OEP - Specialization for <void>
template <> class Null<void> {
public:
  bool is_null;
  typedef void value_type;
public:
  Null () : is_null(false) {} 
  //: 
  Null (const null_type &n) : is_null(true) {} 
  //: Gives Null the null value
  // Note: the global const *null* (not NULL) is of value null_type thus 
  // you can say something like *Null<Type> x = null*.
  //:
  Null& operator = (const null_type &n) {is_null = true; return *this;}
  //:
};
 
#endif
Added sqlplusint/null2.hh.












1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __null2_hh__
#define __null2_hh__

#include "null1.hh"

template <class Type, class Behavior>
inline ostream& operator << (ostream &o, const Null<Type,Behavior> &n) {
  if (n.is_null) return Behavior::null_ostr(o);
  else return o << n.data;
}

#endif
Added sqlplusint/null3.hh.


1
2
+
+

#include "null2.hh"
Added sqlplusint/query.cc.





















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "query3.hh"

MysqlQuery::MysqlQuery(const MysqlQuery &q) : SQLQuery(q) {
  throw_exceptions = q.throw_exceptions;
  mysql = q.mysql;
}

MysqlQuery& MysqlQuery::operator = (const MysqlQuery &q) {
  throw_exceptions = q.throw_exceptions;
  mysql = q.mysql;
  SQLQuery::operator = (q);
  return *this;
}







Added sqlplusint/query1.hh.






































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __query1_hh__
#define __query1_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <mysql.h>
#include "define_short"
#include "sql_query1.hh"
#include "result1.hh"
#include "connection1.hh"


//: A Query class suitable for executing queries.  
// This is the class is subclassed from SQLQuery. This class unlike
// SQLQuery is loosely attached to a Mysql object so that it can
// execute queries.
class Query : public SQLQuery {
private:
  Connection   *mysql;
  bool         throw_exceptions;

  int     affected_rows() const;
  int     insert_id ();
  string  info ();
  bool    lock();
  void    unlock();

public:
  Query(Connection *m, bool te = false) 
    {mysql = m;errmsg=NULL;Success = true;throw_exceptions=te;} 
  //: Create a new query object attached to a connection.
  Query(const Query &q); //:
  Query& operator = (const Query &q); //:

  string   error ();  //: The error message if the query was not successful.
  bool     success(); //: Displays the string currently in the buffer.
  // Same thing as string().

  string   preview () {return str(def);}       //:
  string   preview (parms &p) {return str(p);} //:

  //!dummy: MysqlResNSel execute (...);
  //: Executes the query in the string buffer.
  // Executes the query in the string buffer and returns a structure
  // that contains the information of the success of the query. Use
  // this for queries that don't return a result set such as INSERT,
  // UPDATE, etc.
  //
  // The parameters can be anything in a valid SQLQuery::str.

  //!dummy: MysqlRes store (...);
  //: Executes the query in the string buffer.
  // Executes a query in the string buffer and returns the result.
  //
  // The parameters can be anything in a valid SQLQuery::str.

  //!dummy: MysqlResUse use (...); 
  //: Executes the query in the string buffer.
  // Executes the query in the string buffer and returns the
  // results. This method used the mysql_use_result(MYSQL_RES)
  // function and thus should be used sparingly. Also the Result set is
  // a lot more limited and DOES NOT have an iterator.
  //
  // The parameters can be anything in a valid SQLQuery::str.

  mysql_query_define0(string,preview)

  mysql_query_define1(ResNSel, execute)
  mysql_query_define1(ResUse, use)
  mysql_query_define1(Result, store) 

  mysql_query_define2(storein_sequence)
  mysql_query_define2(storein_set)

  mysql_query_define2(storein)

  template <class T> Query& update(const T &o, const T &n) {
    SQLQuery::update(o,n);
    return *this;
  }
  
  template <class T> Query& insert(const T &v) {
    SQLQuery::insert(v);
    return *this;
  }

  template <class T> Query& replace(const T &v) {
    SQLQuery::replace(v);
    return *this;
  }
};

#endif





Added sqlplusint/query2.hh.




































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#ifndef __query2_hh__
#define __query2_hh__

#include "query1.hh"
#include "connection2.hh"
#include "coldata2.hh"

inline bool Query::success() {
  if (!Success) return false;
  return mysql->success();
}

inline ResNSel Query::execute(const char* str) {
  return mysql->execute(str);
}

inline ResNSel Query::execute(parms &p, query_reset r)
{
  r = (parsed.size()) ? DONT_RESET : RESET_QUERY;
  return mysql->execute(str(p,r));
}

inline ResUse Query::use(const char* str) {
  return mysql->use(str);
}

inline ResUse Query::use(parms &p, query_reset r) {
  r = (parsed.size()) ? DONT_RESET: RESET_QUERY;
  return mysql->use(str(p,r));
}

inline Result Query::store(const char* str) {
  return mysql->store(str);
}

inline Result Query::store(parms &p, query_reset r) {
  r = (parsed.size()) ? DONT_RESET: RESET_QUERY;
  return mysql->store(str(p,r));
}

inline int Query::affected_rows() const {
  return mysql->affected_rows();
}

inline int Query::insert_id () {
  return mysql->insert_id();
}

inline string Query::info() {
  return mysql->info();
}

inline string Query::error () {
  if (errmsg) return string(errmsg);
  return mysql->error();
}

inline void Query::unlock() {
  mysql->unlock();
}

template <class Seq>
inline void Query::storein_sequence (Seq &seq,parms &p, query_reset r) {
  r = (parsed.size()) ? DONT_RESET : RESET_QUERY;
  mysql->storein_sequence (seq, str(p,r));
}

template <class Set>
inline void Query::storein_set (Set &sett, parms &p, query_reset r) {
  r = (parsed.size()) ? DONT_RESET : RESET_QUERY;
  mysql->storein_set (sett, str(p,r));
}

template <class Sequence>
inline void Query::storein_sequence (Sequence &seq, const char *s) {
  mysql->storein_sequence (seq, s);
}

template <class Set>
inline void Query::storein_set (Set &sett, const char * s) {
  mysql->storein_set (sett, s);
}

template <class T>
inline void Query::storein (T &con, parms &p, query_reset r) {
  r = (parsed.size()) ? DONT_RESET : RESET_QUERY;
  mysql->storein (con, str(p,r));
}

template <class T>
inline void Query::storein (T &con, const char *s) {
  mysql->storein (con, s);
}

#endif




Added sqlplusint/query3.hh.


1
2
+
+

#include "query2.hh"
Added sqlplusint/resiter1.hh.








































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __resiter1_hh__
#define __resiter1_hh__

#include "defs"
#include "row1.hh"
#include <iterator.h>

template <class OnType, class ReturnType, class SizeType, class DiffType>
class subscript_iterator;

//: A container adapter to make a container into a Random Access Container.

// The requirements are that the container has the member functions
// *operator[] (SizeType)* _and_  *size()* defined. 

template <class OnType, class ValueType, class ReturnType = const ValueType&, class SizeType = unsigned int, class DiffType = int>
class const_subscript_container {
public:
  typedef const_subscript_container<OnType,ValueType,ReturnType,SizeType,DiffType>
                                    this_type; //:

  typedef subscript_iterator<const this_type, ReturnType, SizeType, DiffType> 
                                                 iterator;   //:
  typedef iterator                               const_iterator; //:
  typedef const ::reverse_iterator<iterator>       reverse_iterator; //:
  typedef const ::reverse_iterator<const_iterator> const_reverse_iterator; //:
  
  typedef ValueType   value_type; //:
  typedef value_type& reference;  //:
  typedef value_type& const_reference; //:
  typedef value_type* pointer; //:
  typedef value_type* const_pointer; //:
  
  typedef DiffType          difference_type; //:
  typedef SizeType          size_type; //:
  
  virtual size_type  size() const = 0; //:
  virtual ReturnType operator[] (SizeType i) const = 0; //:

  size_type max_size() const {return size();}    //:
  bool      empty()    const {return size()==0;} //:
  
  iterator  begin() const {return iterator(this, 0);}      //:
  iterator  end()   const {return iterator(this, size());} //:
  
  reverse_iterator rbegin() const {return reverse_iterator(end());}   //:
  reverse_iterator rend()   const {return reverse_iterator(begin());} //:
};

//:
template <class OnType, class ReturnType, class SizeType, class DiffType>
class subscript_iterator : public random_access_iterator<ReturnType, SizeType>
{
private:
  SizeType    i;
  OnType     *d;
public:
  subscript_iterator() {}; 
  subscript_iterator(OnType *what, SizeType pos) {d=what; i=pos;}
 
  bool operator == (const subscript_iterator &j) const
    {if (d == j.d && i==j.i) return true; return false;}
  bool operator != (const subscript_iterator &j) const
    {if (d == j.d && i!=j.i) return true; return false;}
  bool operator < (const subscript_iterator &j) const
    {if (d == j.d && i < j.i) return true; return false;}
  bool operator > (const subscript_iterator &j) const
    {if (d == j.d && i > j.i) return true; return false;}
  bool operator <= (const subscript_iterator &j) const
    {if (d == j.d && i<=j.i) return true; return false;}
  bool operator >= (const subscript_iterator &j) const
    {if (d == j.d && i>=j.i) return true; return false;}

  ReturnType operator -> () const {return &((*d)[i]);}
  ReturnType operator *  () const {return (*d)[i];}
  ReturnType operator [] (SizeType n) const {return (*d)[n];}

  subscript_iterator& operator ++ () {i++; return *this;}
  subscript_iterator  operator ++ (int) 
    {subscript_iterator tmp = *this; i++; return tmp;}
  subscript_iterator& operator -- () {i--; return *this;}
  subscript_iterator  operator -- (int) 
    {subscript_iterator tmp = *this; i--; return tmp;}
  subscript_iterator& operator += (SizeType n) {i=i+n; return *this;}
  subscript_iterator  operator + (SizeType n) const
    {subscript_iterator tmp = *this; tmp.i+=n; return tmp;}
  subscript_iterator& operator -= (SizeType n) {i=i-n; return *this;}
  subscript_iterator  operator - (SizeType n) const
    {subscript_iterator tmp = *this; tmp.i-=n; return tmp;}
  DiffType operator - (const subscript_iterator &j) const
    {if (d == j.d) return (SizeType)i - j.i; return 0;}
};

template <class OnType, class ReturnType, class SizeType, class DiffType>
inline subscript_iterator<OnType,ReturnType,SizeType,DiffType> operator + 
(SizeType x, const subscript_iterator <OnType,ReturnType,SizeType,DiffType>& y) 
{
  return y + x;
}

#endif



Added sqlplusint/result.cc.

















































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "result3.hh"

pointer_tracker<MYSQL_RES, ResUse> ResUse::others =  pointer_tracker<MYSQL_RES, ResUse>();

ResUse::ResUse (MYSQL_RES *result, Connection *m, bool te) 
  : mysql(m), mysql_res(result), throw_exceptions(te), _names(NULL), _types(NULL), _fields(this)
{
  _table = fields(0).table;
  if (mysql) mysql->add_child(this);
  others.insert(mysql_res,this);
}

ResUse::~ResUse () {
  if (mysql) mysql->unlock(); 
  if (mysql) mysql->remove_child(this);
  others.remove(mysql_res,this);
}

void ResUse::copy(const ResUse& other) {
  throw_exceptions = other.throw_exceptions;
  mysql_res = other.mysql_res;
  _fields   = other._fields;
  if (other._names)
    _names     = new FieldNames(*other._names);
  else
    _names     = NULL;
  if (other._types)
    _types     = new FieldTypes(*other._types);
  else
    _types     = NULL;
  mysql     = other.mysql;
  if (mysql) mysql->add_child(this);
  others.insert(mysql_res,this);
}

void MutableRes::populate(ResUse res) {
  Row row = res.fetch_row();
  _columns = row.size();
  while (row) {
    parent::push_back(MutableRow<MutableRes>(row, this));
    row = res.fetch_row();
  }
}





Added sqlplusint/result1.hh.





























































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __result1_hh__
#define __result1_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <map.h>
#include <set.h>
#include <mysql.h>
#include <string>
#include "define_short"
#include "field_names1.hh"
#include "row1.hh"
#include "resiter1.hh"
#include "tracker.h"
#include "field_types1.hh"
#include "fields1.hh"

#include "connection0.hh"

//:
class ResUse : public MysqlChild {
  friend Connection;
protected:
  Connection            *mysql;
  mutable MYSQL_RES     *mysql_res;
  bool                  throw_exceptions;
  mutable FieldNames    *_names;
  mutable FieldTypes    *_types;
  Fields                _fields;
  string                _table;       

  static pointer_tracker<MYSQL_RES, ResUse> others;

  void copy(const ResUse& other); 
public:
  ResUse () : mysql(0), mysql_res(0), throw_exceptions(false), _names(NULL), _types(NULL), _fields(this) {}
  ResUse (MYSQL_RES *result, Connection *m = NULL, bool te = false);
  ResUse (const ResUse &other) {copy(other);}
  inline ResUse& operator = (const ResUse &other);
  MYSQL_RES *mysql_result (void) {return mysql_res;}
  /* raw mysql c api functions */
  Row fetch_row()
    {return Row(mysql_fetch_row(mysql_res), this, throw_exceptions);}
  //: raw c api function
  bool          eof () const {return mysql_eof(mysql_res);}
  //: raw c api function
  long unsigned int *fetch_lengths () const {return mysql_fetch_lengths(mysql_res);}
  //: raw c api function
  void         free_result() {mysql_free_result(mysql_res);}
  //: raw c api function

  /* raw mysql c api fields functions */
  Field&       fetch_field () const   {return *mysql_fetch_field(mysql_res);}
  //: raw c api field function
  void         field_seek (int field) {mysql_field_seek (mysql_res, field);}
  //: raw c api field function
  int          num_fields() const {return mysql_num_fields(mysql_res);}
  //: raw c api field function

  ~ResUse (); 

  void parent_leaving() {mysql = NULL;}
  
  void purge(MYSQL_RES *r)
    { if (mysql_res) mysql_free_result(mysql_res); mysql_res=0; if (_names) delete _names; if (_types) delete _types; _names=0; _types=0; _table.erase(); }
  
  operator bool() const {if (mysql_res) return true; return false;} //:
  unsigned int columns() const {return num_fields();} //:

  string& table() {return _table;}
  //: table name
  const string& table() const {return _table;}
  //: table name

  /* methods for working with field names */
  inline int               field_num(const string&) const;
  //: Returns the offset of the filed which equals str.
  inline string&           field_name(int);
  //: Returns the field with an offset of i.
  inline const string&     field_name(int) const;
  //: Returns the field with an offset of i.
  inline FieldNames&       field_names();
  //: Returns a reference to the underlying FieldNames class.
  inline const FieldNames& field_names() const;
  //: Returns a const reference to the underlaying FieldNames class.
  inline void              reset_field_names();
  //: Resets the field names to there original values.

  /* methods for working with field types */
  inline mysql_type_info&  field_type(int i);
  //: Returns a reference to the  mysql field type for the field with an offset of i.
  inline const mysql_type_info& field_type(int) const;
  //: Returns a const reference to the  mysql field type for the field with an offset of i.
  inline FieldTypes&       field_types();
  //: Returns a reference to the underlying FieldTypes
  inline const FieldTypes& field_types() const;
  //: Returns a const reference to the underlying FieldTypes
  inline void              reset_field_types();
  //: Resets the field_types to their original values.

  /* short names for the above methods */
  inline int               names(const string& s) const;
  //: Returns the offset of the filed which equals str.
  inline string&           names(int i);
  //: Returns the field with an offset of i.
  inline const string&     names(int i) const;
  //: Returns the field with an offset of i.
  inline FieldNames&       names();
  //: Returns a reference to the underlying FieldNames class.
  inline const FieldNames& names() const;
  //: Returns a const reference to the underlying FieldNames class.
  inline void              reset_names();
  //: Resets the field names to their original values.

  inline mysql_type_info&  types(int i);
  //: Returns a reference to the  mysql field type for the field with an offset of i.
  inline const mysql_type_info& types(int i) const;
  //: Returns a const reference to the mysql field type for the field with an offset of i.
  inline FieldTypes&       types();
  //: Returns a reference to the underlying FieldTypes
  inline const FieldTypes& types() const;
  //: Returns a const reference to the underlying FieldTypes
  inline void              reset_types();
  //: Resets the field_types to their original values.
  
  /* methods for working with field info */
  const Fields&     fields() const {return _fields;}
  //: returns a reference to the underling Fields structure.
  const Field&      fields(unsigned int i) const {return _fields[i];}
  //: returns a reference to the the mysql field info for a field with an offset of i.

  bool     operator == (const ResUse &other) const
    {return mysql_res == other.mysql_res;}
  //:
  bool     operator != (const ResUse &other) const
    {return mysql_res != other.mysql_res;}
  //:
};

//: This class handles the result set. 
// It is also a Random Access Container that is not LessThanComparable
// and not Assignable. Being a Random Access Container it can
// return a Random Access Iterator or a reverse Random Access Iterator
// yet.
//
// See MutableRes for a result set that can be modified.
class Result : public ResUse, 
	       public const_subscript_container<Result,Row,const Row>
{
  friend Connection;
public:
  Result () {} //:
  Result (MYSQL_RES *result, bool te = false) 
    : ResUse(result, NULL, te) {mysql = NULL;} //:
  Result (const Result &other) : ResUse(other) {mysql = NULL;} //:
  
  // raw mysql c api functions
  const Row    fetch_row() const
    {return Row(mysql_fetch_row(mysql_res), this, throw_exceptions);}  
  //: Raw c api function
  int          num_rows() const {return mysql_num_rows(mysql_res);}
  //: Raw c api function
  void         data_seek (uint offset) const 
    {mysql_data_seek(mysql_res, offset);}
  //: Raw c api function

  size_type size() const {return num_rows();}
  //: Returns the number of columns.
  size_type rows() const {return num_rows();}
  //: Returns the number of rows.
  const Row operator [] (size_type i) const {data_seek(i); return fetch_row();}
  //: Returns the row with an offset of i.
};

class MutabelRes;

//: This class handles the result set. 
// It is also a Random Access Container that is not LessThanComparable
// but is Assignable. Being a Random Access Container it can
// return a Random Access Iterator or a reverse Random Access Iterator
// yet.
//
class MutableRes : public vector<MutableRow<MutableRes> > {
private:
  size_type  _columns;
  FieldNames _names;
  void populate(ResUse res);

  typedef vector<MutableRow<MutableRes> >  parent;
public:
  MutableRes() {}  //:
  MutableRes(ResUse res) : _names(&res) {populate(res);} //:
  MutableRes(size_type i) : _columns(i), _names (i) {} 
  //: Creates a new mutable result set with i columns.

  MutableRes& operator = (ResUse res) {
    _names=&res; populate(res); return *this;
  } //: 
  MutableRes& operator = (size_type i) {
    _columns = i; _names = i; return *this;
  } //:

  size_type rows() const {return size();}
  //: Returns the number of rows.
  size_type columns() const {return _columns;}
  //: Returns the number of columns.

  /* methodes for inserting elements as the standart insert functions
     won't work that well as MutableRow needs to be constructed in a
     special way */

  iterator insert(iterator pos) {return parent::insert(pos, value_type(this));} 
  void insert(iterator pos, size_type n) {parent::insert(pos, n, value_type(this));}
  void push_back() {parent::push_back(value_type(this));}

  /* methods for working with field names */

  inline int               field_num(const string& str) const;
  //: Returns the offset of the filed which equals str.
  inline string&           field_name(int i);
  //: Returns the field with an offset of i.
  inline const string&     field_name(int i) const;
  //: Returns the field with an offset of i.
  inline FieldNames&       field_names();
  //: Returns a reference to the underlying FieldNames class.
  inline const FieldNames& field_names() const;
  //: Returns a const reference to the underlying FieldNames class.

  // short names for the above methods
  inline int               names(const string& s) const;
  //: Returns the offset of the filed which equals str.
  inline string&           names(int i);
  //: Returns the field with an offset of i.
  inline const string&     names(int i) const;
  //: Returns the field with an offset of i.
  inline FieldNames&       names();
  //: Returns a reference to the underlying FieldNames class.
  inline const FieldNames& names() const;
  //: Returns a const reference to the underlying FieldNames class.
};

//! with_class = ResUSe

//:
inline void swap (ResUse &x, ResUse &y) {
  ResUse tmp = x;
  x = y;
  y = tmp;
}

//! with_class = Result

//:
inline void swap (Result &x, Result &y) {
  Result tmp = x;
  x = y;
  y = tmp;
}

//: This structure holds the information on the success of queries that
//: don't return any results.
struct ResNSel {
  bool     success;   
  int      insert_id; //: 
  int      rows;      //: Number of rows affected
  string   info;      //: Additional info

  ResNSel() : success(false) {};
  ResNSel (Connection *q);

  operator bool() {return success;}  //: If the query was successful
};  


#endif






Added sqlplusint/result2.hh.






























































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __result2_hh__
#define __result2_hh__

#include "connection2.hh"
#include "result1.hh"
#include "row2.hh"
#include "fields2.hh"

// field name info

inline int ResUse::field_num(const string &i) const {
  if (!_names) _names = new FieldNames(this);
  return (*_names)[i];
}

inline string& ResUse::field_name(int i) {
  if (!_names) _names = new FieldNames(this);
  return (*_names)[i];
}

inline const string& ResUse::field_name(int i) const {
  if (!_names) _names = new FieldNames(this);
  return (*_names)[i];
}

inline FieldNames& ResUse::field_names() {
  if (!_names) _names = new FieldNames(this);
  return *_names;
}

inline const FieldNames& ResUse::field_names() const {
  if (!_names) _names = new FieldNames(this);
  return *_names;
}

inline void ResUse::reset_field_names() {
  delete _names;
  _names = new FieldNames(this);
}

// field type info

inline mysql_type_info& ResUse::field_type(int i) {
  if (!_types) _types = new FieldTypes(this);
  return (*_types)[i];
}

inline const mysql_type_info& ResUse::field_type(int i) const {
  if (!_types) _types = new FieldTypes(this);
  return (*_types)[i];
}

inline FieldTypes& ResUse::field_types() {
  if (!_types) _types = new FieldTypes(this);
  return *_types;
}

inline const FieldTypes& ResUse::field_types() const {
  if (!_types) _types = new FieldTypes(this);
  return *_types;
}

inline void ResUse::reset_field_types() {
  delete _types;
  _types = new FieldTypes(this);
}

inline int               ResUse::names(const string& s) const {return field_num(s);}
inline string&           ResUse::names(int i) {return field_name(i);}
inline const string&     ResUse::names(int i) const {return field_name(i);}
inline FieldNames&       ResUse::names() {return field_names();}
inline const FieldNames& ResUse::names() const {return field_names();}
inline void              ResUse::reset_names() {reset_field_names();}

inline mysql_type_info&  ResUse::types(int i) {return field_type(i);}
inline const mysql_type_info& ResUse::types(int i) const {return field_type(i);}
inline FieldTypes&       ResUse::types() {return field_types();}
inline const FieldTypes& ResUse::types() const {return field_types();}
inline void              ResUse::reset_types() {reset_field_types();}

//

inline int MutableRes::field_num(const string &i) const {
  return _names[i];
}

inline string& MutableRes::field_name(int i) {
  return _names[i];
}

inline const string& MutableRes::field_name(int i) const {
  return _names[i];
}

inline FieldNames& MutableRes::field_names() {
  return _names;
}

inline const FieldNames& MutableRes::field_names() const {
  return _names;
}

//

inline int               MutableRes::names(const string& s) const {return field_num(s);}
inline string&           MutableRes::names(int i) {return field_name(i);}
inline const string&     MutableRes::names(int i) const {return field_name(i);}
inline FieldNames&       MutableRes::names() {return field_names();}
inline const FieldNames& MutableRes::names() const {return field_names();}

//

inline ResUse& ResUse::operator = (const ResUse &other) {
  others.remove(mysql_res,this);
  copy(other);
  return *this;
}

inline ResNSel::ResNSel (Connection *q) 
  : success   (q->success()),         insert_id (q->insert_id()),
    rows      (q->affected_rows()),   info      (q->info())        {}

#endif



Added sqlplusint/result3.hh.


1
2
+
+

#include "result2.hh"
Added sqlplusint/row.cc.






























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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "result1.hh"
#include "row3.hh"

MutableRow<ResUse>::MutableRow(const Row &r) : MutableRow_base<ResUse>(r.res) {
  if (r) {
    reserve(r.size());
    for (size_type i = 0; i < r.size(); i++) {
      push_back(r.raw_data(i));
    }
  }
}

MutableRow<ResUse>::MutableRow(const ResUse &r) : MutableRow_base<ResUse>(&r) {
  insert(begin(), r.columns(), MutableColData());
}

MutableRow<MutableRes>::MutableRow(const Row &r, const MutableRes *_res) 
  : MutableRow_base<MutableRes>(_res) 
{
  if (r) {
    reserve(r.size());
    for (size_type i = 0; i < r.size(); i++) {
      push_back(r.raw_data(i));
    }
  }
}



Added sqlplusint/row1.hh.
























































































































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __row1_hh__
#define __row1_hh__

#include <vector>
#include <string>
#include "defs"
#include "define_short"
//#include "result1.hh"
#include "coldata1.hh"
#include "resiter1.hh"
#include "vallist1.hh"

template <class ThisType, class Res>
class RowTemplate {
protected:
  virtual ThisType& self() = 0;
  virtual const ThisType& self() const = 0;
public:
  virtual const Res & parent() const = 0;
  
  // 
  // value_list
  //
  value_list_ba<ThisType,quote_type0> 
  value_list(const char *d = ",") const {
    return value_list_ba<ThisType,quote_type0> 
      (self(), d, quote);
  }

  template <class Manip>  
  value_list_ba<ThisType,Manip> 
  value_list(const char *d, Manip m) const {
    return value_list_ba<ThisType,Manip> (self(), d, m);
  }

  template <class Manip>  
  value_list_b<ThisType,Manip> 
  value_list(const char *d, Manip m, const vector<bool> &vb) const {
    return value_list_b<ThisType,Manip> (self(), vb, d, m);
  }

  value_list_b<ThisType,quote_type0> 
  value_list(const char *d, const vector<bool> &vb) const {
    return value_list_b<ThisType,quote_type0> (self(), vb, d, quote);
  }

  value_list_b<ThisType,quote_type0> 
  value_list(const vector<bool> &vb) const {
    return value_list_b<ThisType,quote_type0> (self(), vb, ",", quote);
  }

  template <class Manip>  
  value_list_b<ThisType,Manip> 
  value_list(const char *d, Manip m, bool t0,
	     bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	     bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	     bool t9=false, bool ta=false, bool tb=false, bool tc=false) const {
    vector<bool> vb;
    create_vector(self().size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
    return value_list_b<ThisType, Manip>(self(), vb, d, m);
  }

  value_list_b<ThisType,quote_type0> 
  value_list(const char *d, bool t0,
	     bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	     bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	     bool t9=false, bool ta=false, bool tb=false, bool tc=false) const {
    vector<bool> vb;
    create_vector(self().size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
    return value_list_b<ThisType, quote_type0>(self(), vb, d, quote);
  }

  value_list_b<ThisType,quote_type0> 
  value_list(bool t0,
	     bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	     bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	     bool t9=false, bool ta=false, bool tb=false, bool tc=false) const {
    vector<bool> vb;
    create_vector(self().size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
    return value_list_b<ThisType, quote_type0>(self(), vb, ",", quote);
  }

  template <class Manip>
  value_list_b<ThisType,Manip> 
  value_list(const char *d, Manip m, string s0,
	     string s1="", string s2="", string s3="", string s4="",
	     string s5="", string s6="", string s7="", string s8="",
	     string s9="", string sa="", string sb="", string sc="") const {
    vector<bool> vb;
    create_vector(self(), vb, s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc);
    return value_list_b<ThisType, Manip>(self(), vb, d, m);
  }

  value_list_b<ThisType,quote_type0> 
  value_list(const char *d, string s0,
	     string s1="", string s2="", string s3="", string s4="",
	     string s5="", string s6="", string s7="", string s8="",
	     string s9="", string sa="", string sb="", string sc="") const {
    vector<bool> vb;
    create_vector(self(), vb, s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc);
    return value_list_b<ThisType, quote_type0>(self(), vb, d, quote);
  }

  value_list_b<ThisType,quote_type0> 
  value_list(string s0,
	     string s1="", string s2="", string s3="", string s4="",
	     string s5="", string s6="", string s7="", string s8="",
	     string s9="", string sa="", string sb="", string sc="") const {
    vector<bool> vb;
    create_vector(self(), vb, s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc);
    return value_list_b<ThisType, quote_type0>(self(), vb, ",", quote);
  }

  //
  // field_list
  //
  value_list_ba<FieldNames, do_nothing_type0> 
  field_list(const char *d = ",") const {
    return value_list_ba<FieldNames, do_nothing_type0> 
      (parent().names(), d, do_nothing);
  }

  template <class Manip>  
  value_list_ba<FieldNames,Manip> 
  field_list(const char *d, Manip m) const {
    return value_list_ba<FieldNames, Manip>
      (parent().names(), d, m);
  }

  template <class Manip>  
  value_list_b<FieldNames,Manip> 
  field_list(const char *d, Manip m, const vector<bool> &vb) const {
    return value_list_b<FieldNames,Manip> (parent().names(), vb, d, m);
  }

  value_list_b<FieldNames,quote_type0> 
  field_list(const char *d, const vector<bool> &vb) const {
    return value_list_b<FieldNames,quote_type0> (parent().names(), vb, d, quote);
  }

  value_list_b<FieldNames,quote_type0> 
  field_list(const vector<bool> &vb) const {
    return value_list_b<FieldNames,quote_type0> (parent().names(), vb, ",", quote);
  }

  template <class Manip>  
  value_list_b<FieldNames,Manip> 
  field_list(const char *d, Manip m, bool t0,
	     bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	     bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	     bool t9=false, bool ta=false, bool tb=false, bool tc=false) const {
    vector<bool> vb;
    create_vector(parent().names().size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
    return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
  }

  value_list_b<FieldNames,quote_type0> 
  field_list(const char *d, bool t0,
	     bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	     bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	     bool t9=false, bool ta=false, bool tb=false, bool tc=false) const {
    vector<bool> vb;
    create_vector(parent().names().size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
    return value_list_b<FieldNames, quote_type0>(parent().names(), vb, d, quote);
  }

  value_list_b<FieldNames,quote_type0> 
  field_list(bool t0,
	     bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	     bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	     bool t9=false, bool ta=false, bool tb=false, bool tc=false) const {
    vector<bool> vb;
    create_vector(parent().names().size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
    return value_list_b<FieldNames, quote_type0>(parent().names(), vb, ",", quote);
  }

  template <class Manip>
  value_list_b<FieldNames,Manip> 
  field_list(const char *d, Manip m, string s0,
	     string s1="", string s2="", string s3="", string s4="",
	     string s5="", string s6="", string s7="", string s8="",
	     string s9="", string sa="", string sb="", string sc="") const {
    vector<bool> vb;
    create_vector(parent().names(), vb, s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc);
    return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
  }

  value_list_b<FieldNames,quote_type0> 
  field_list(const char *d, string s0,
	     string s1="", string s2="", string s3="", string s4="",
	     string s5="", string s6="", string s7="", string s8="",
	     string s9="", string sa="", string sb="", string sc="") const {
    vector<bool> vb;
    create_vector(parent().names(), vb, s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc);
    return value_list_b<FieldNames, quote_type0>(parent().names(), vb, d, quote);
  }

  value_list_b<FieldNames,quote_type0> 
  field_list(string s0,
	     string s1="", string s2="", string s3="", string s4="",
	     string s5="", string s6="", string s7="", string s8="",
	     string s9="", string sa="", string sb="", string sc="") const {
    vector<bool> vb;
    create_vector(parent().names(), vb, s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc);
    return value_list_b<FieldNames, quote_type0>(parent().names(), vb, ",", quote);
  }

  //
  // equal_list
  //
  equal_list_ba<FieldNames,ThisType,quote_type0> 
  equal_list(const char *d = ",", const char *e = " = ") const {
    return equal_list_ba<FieldNames,ThisType,quote_type0> 
      (parent().names(), self(), d, e, quote);
  }

  template <class Manip>
  equal_list_ba<FieldNames,ThisType,Manip> 
  equal_list(const char *d, const char *e, Manip m) const {
    return equal_list_ba<FieldNames,ThisType,Manip> 
      (parent().names(), self(), d, e, m);
  }

  virtual ~RowTemplate() {}
};

class MutableRes;
template <class Res = ResUse> class MutableRow;

//: This class handles the actual rows in an intelligent manner.
class Row : public const_subscript_container<Row,ColData,const ColData>,
	    public RowTemplate<Row, ResUse>
{
  friend MutableRow<ResUse>;
  friend MutableRow<MutableRes>;
private:
//  MYSQL_ROW    data;
  vector <string> data;
  const ResUse *res;
  bool         throw_exceptions;

public:
  Row() {}
  Row(MYSQL_ROW d, const ResUse *r, bool te = false) 
    : res(r), throw_exceptions(te) 
		{
		  if (!d) return;
		  data.clear();
		  for (unsigned int i=0;i<size();i++) 
			{
			  data.insert(data.end(),(d[i]) ? (string)d[i] : (string)"");
			}
		}
  const Row& self() const {return *this;}
  Row& self() {return *this;}

  const ResUse&  parent() const {return *res;}
  inline size_type     size() const;
  //: Returns the number of columns.
  const ColData   operator [] (int i) const {return operator[](size_type(i));}
  inline const ColData   operator [] (size_type i) const;
  //: Returns the value of the field with the index of i.
  inline const ColData   operator [] (const char *) const;
  //: Returns the value of the field with the field name of i.
  // This method is not nearly as efficient as using the index number. Use sparingly. 
  inline const ColData   operator [] (const string &i) const;
  //: Returns the value of the field with the field name of i.
  // This method is not nearly as effecent as using the index number. Use sparingly. 

  const char * raw_data(int i) const {return data[i].c_str();}

  operator bool() const {return (data.size()) ? true : false;}
  //: Returns true if there is data in the row.
	~Row() {data.clear();}	
}; 

//! with_class = MutableRow

//: This class handles the actual rows with the added benefit of being able to modify the data.
template <class Res>
class MutableRow_base : public vector<MutableColData>, 
			public RowTemplate<MutableRow_base<Res>, Res>
{
private:
  const Res *res;
  typedef vector<MutableColData> parent_type;
protected:
  MutableRow_base& self() {return *this;}
  const MutableRow_base& self() const {return *this;}
  MutableRow_base() {}
  MutableRow_base (const Res *r) : res(r) {}
public:
  const Res& parent() const {return *res;}

  string& table() {return res->table();}
  const string& table() const {return res->table();}

  MutableColData&  operator [] (int i) 
    {return parent_type::operator [](i);}
  //: Returns the value of the field with the index of i.
  MutableColData&  operator [] (unsigned int i) 
    {return parent_type::operator [](i);}
  const MutableColData&  operator [] (int i) const
    {return parent_type::operator [](i);}
  //: Returns the value of the field with the index of i.
  const MutableColData&  operator [] (unsigned int i) const
    {return parent_type::operator [](i);}

  MutableColData&  operator [] (const char *);
  MutableColData&  operator [] (const string &i);
  //: Returns the value of the field with the field name of i.
  // This method is not nearly as efficient as using the index number. Use sparingly. 

  const MutableColData&  operator [] (const char *) const;
  const MutableColData&  operator [] (const string &i) const;
  //: Returns the value of the field with the field name of i.
  // This method is not nearly as efficient as using the index number. Use sparingly. 

  operator bool() const {return empty();}
  //: Returns true if there is data in the row.
};

template <class Res> class MutableRow {};


//:
//!dummy: template <class Res = ResUse> class MutableRow : public MutableRow_base<Res> {};

class MutableRow<ResUse> : public MutableRow_base<ResUse> {
public:
  MutableRow(const Row& row);
  MutableRow(const ResUse &res);
};

class MutableRow<MutableRes> : public MutableRow_base<MutableRes> {
public:
  MutableRow(const Row& row, const MutableRes *_res); 
  inline MutableRow(const MutableRes *_res);        
};


#endif


Added sqlplusint/row2.hh.






























































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __row2_hh__
#define __row2_hh__

#include "string.h"
#include "row1.hh"
#include "result2.hh"

inline Row::size_type Row::size() const {return res->num_fields();}

inline const ColData Row::operator [] (size_type i) const {
  return ColData(data[i].c_str(), res->types(i));
}

inline const ColData Row::operator[] (const string &i) const {
  return (*this)[res->field_num(i)];
}

inline const ColData Row::operator[] (const char *i) const {
  return (*this)[res->field_num(string(i))];
}

// MutableRow

inline MutableRow<MutableRes>::MutableRow(const MutableRes *_res)
  : MutableRow_base<MutableRes>(_res)
{
  insert(begin(), _res->columns(), "");
}

template <class Res>
inline MutableColData& MutableRow_base<Res>::operator[] (const string &i) {
  return (*this)[res->field_num(i)];
}

template <class Res>
inline MutableColData& MutableRow_base<Res>::operator[] (const char *i) {
  return (*this)[res->field_num(string(i))];
}

template <class Res>
inline const MutableColData& MutableRow_base<Res>::operator[] (const string &i) const {
  return (*this)[res->field_num(i)];
}

template <class Res>
inline const MutableColData& MutableRow_base<Res>::operator[] (const char *i) const {
  return (*this)[res->field_num(string(i))];
}

// RowTemplate

#endif










Added sqlplusint/row3.hh.


1
2
+
+

#include "row2.hh"
Added sqlplusint/set.cc.




1
2
3
4
+
+
+
+

#include "set3.hh"

template class Set<set<string> >;
Added sqlplusint/set1.hh.















































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __set1_hh__
#define __set1_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <set>
#include <vector>
#include <iostream.h>
#include "define_short"
#include "coldata1.hh"

template <class T, class value_type = typename T::value_type>
class MysqlListInsert {
private:
  T *object;
public:
  MysqlListInsert(T *o) {object = o;}
  void operator () (const value_type &data) {object->push_back(data);}
};

template <class T, class key_type = typename T::key_type> 
class MysqlSetInsert {
private:
  T *object;
public:
  MysqlSetInsert(T *o) {object = o;}
  void operator () (const key_type &data) {object->insert(data);}
};

template <class T>
inline MysqlSetInsert<set<T> > set_insert(set<T> *o) {
  return MysqlSetInsert<set<T> >(o);
}

template <class T>
inline MysqlListInsert<vector<T> > set_insert(vector<T> *o) {
  return MysqlListInsert<vector<T> >(o);
}

template <class Insert>
void set2container (const char *str, Insert insert);

//: A Special Set for holding mysql sets.
template <class Container = set<string> >
class Set : public Container {
public:
  Set(const char* str) {set2container(str,set_insert(this));}           //:
  Set(const string &str) {set2container(str.c_str(),set_insert(this));} //:
  Set(const ColData &str) 
    {set2container(str.c_str(),set_insert(this));}                      //:
  
  ostream& out_stream(ostream &s) const;
  
  operator string ();
};

//! with_class = Set

//:
template <class Container>
inline ostream& operator << (ostream &s, const Set<Container> &d) 
{ 
  return d.out_stream(s); 
}

#endif









Added sqlplusint/set2.hh.












1
2
3
4
5
6
7
8
9
10
11
12
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __set2_hh__
#define __set2_hh__

#include "set1.hh"
#include "stream2string3.hh"

template <class Container> 
inline Set<Container>::operator string () {
  return stream2string<string>(*this);
}

#endif
Added sqlplusint/set3.hh.



































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __set3_hh__
#define __set3_hh__

#include "set2.hh"
#include "coldata2.hh"

template <class Insert>
void set2container (const char *str, Insert insert) {
  MutableColData s;
  while (1) {
    s = "";
    while (*str != ',' && *str) {
      s += *str;
      str++;
    }
    insert(s);
    if (!*str) break;
    str++;
  }
}

template <class Container>
ostream& Set<Container>::out_stream (ostream &s) const {
  typename Container::const_iterator i = begin();
  typename Container::const_iterator e = end();
  while (true) {
    s << *i;
    i++;
    if (i==e) break;
    s << ",";
  }
  return s;
}

#endif
Added sqlplusint/space-fix.pl.
















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#!/usr/bin/perl

$/ = undef;

open F, $ARGV[0];

$_=<F>;

s/ +/ /g;
s/\n /\n/g;
s/\n\n+/\n\n/g;

open F, ">$ARGV[0]";
print F;


Added sqlplusint/sql_query.cc.


















































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "sql_query3.hh"
//#include "result3.hh"

SQLQuery::SQLQuery(const SQLQuery &q) {
  *this << q.str();
  Success = q.Success;
  def = q.def;
}


SQLQuery& SQLQuery::operator = (const SQLQuery &q) {
  reset();
  *this << q.str();
  Success = q.Success;
  def = q.def;
  return *this;
}


void SQLQuery::reset() {
  seekg (0L,ios::beg);
  seekp (0L,ios::beg);
  parsed.erase(parsed.begin(), parsed.end());
  def.clear(); clear();
}

char * SQLQuery::preview_char() {
  *this << ends;
#ifdef __USLC__
  strstreambuf *tmpbuf = rdbuf();
  uint length = tmpbuf->pcount();
#else
  uint length = pcount();
#endif
  char *s = new char[length]; 
  get(s, length, '\0'); 
  seekg (0,ios::beg);
  seekp (-1,ios::cur);
  return s;
}

SQLString * pprepare (char option, SQLString &S, bool replace = true) {
  if (S.processed) return &S;
  if (option == 'r' || (option == 'q' && S.is_string)) {
    char *s = new char[S.size()*2];
    mysql_escape_string(s,const_cast<char *>(S.c_str()),S.size());
    SQLString *ss = new SQLString("'");
    *ss += s;
    *ss += "'";
    delete[] s;
    if (replace) {S = *ss; S.processed = true; return &S;}
    return ss;
  } else if (option == 'R' || (option == 'Q' && S.is_string)) {
    SQLString *ss = new SQLString("'" + S + "'");
    if (replace) {S = *ss; S.processed = true; return &S;}
    return ss;
  } else {
    if (replace) S.processed = true;
    return &S;
  }
}

void SQLQuery::proc(SQLQueryParms& p) {
  seekg (0,ios::beg);
  seekp (0,ios::beg);
  char      num;
  SQLString *ss;
  SQLQueryParms *c;
  for (vector<SQLParseElement>::iterator i = parsed.begin();
       i != parsed.end(); i++) {
    *this << i->before;
    num    = i->num;
    if (num == -1) {
      // do nothing    
    } else {
      if (num < (int)p.size()) c = &p;
      else if (num < (int)def.size()) c = &def;
      else {
	*this << " ERROR";
	throw SQLQueryNEParms("Not enough parameters to fill the template.");
      }
      ss = pprepare(i->option, (*c)[num], c->bound());
      *this << *ss;
      if (ss != &(*c)[num]) delete ss;
    }
  }
} 

string SQLQuery::str(const SQLQueryParms &p) const {
  SQLQuery *const_this = const_cast<SQLQuery *>(this);
  if (!parsed.empty()) const_this->proc(const_cast<SQLQueryParms&>(p));
  *const_this << ends;
#ifdef __USLC__
  strstreambuf *tmpbuf = const_this->rdbuf();
  uint length = tmpbuf->pcount();
  char *s = new char[length]; 
#else
  uint length = const_this->pcount();
  char s[length]; 
#endif
  const_this->get(s, length, '\0'); 
  const_this->seekg (0,ios::beg);
  const_this->seekp (-1,ios::cur);
  return string(s);
}

string SQLQuery::str(const SQLQueryParms &p, query_reset r) {
  string tmp = str(p);
  if (r==RESET_QUERY) reset();
  return tmp;
}

SQLQueryParms SQLQueryParms::operator + (const SQLQueryParms &other) const {
  if (other.size() <= size()) return *this;
  SQLQueryParms New = *this;
  unsigned int i;
  for(i = size(); i < other.size(); i++) {
    New.push_back(other[i]);
  }
  return New;
}

void SQLQuery::parse() {
  string str = "";
  char num[3];
  long int n;
  char option;
  string name;
  char *s, *s0;
  s0 = s = preview_char();
  while (*s) {
    if (*s == '%') {
      s++;
      if (*s == '%') {
	str += *s++;
      } else if (*s >= '0' && *s <= '9') {
	num[0] = *s;
	s++;
	if (*s >= '0' && *s <= '9') {
	  num[1] = *s;
	  num[2] = 0;
          s++;
	} else {
	  num[1] = 0;
	}
        n = strtol(num,NULL,10);
        option = ' ';
        if (*s == 'q' || *s == 'Q' || *s == 'r' || *s == 'R')
	  option = *s++;
	if (*s == ':') {
	  s++;
	  for (;(*s>='A' && *s<='Z') || *s=='_' || (*s>='a' && *s<='z'); s++) {
	    name += *s;
	  }
	  if (*s == ':') s++;
          if (n >= (long int)parsed_names.size())
	    parsed_names.insert(parsed_names.end(),
				(vector<string>::size_type)(n+1) 
				- parsed_names.size(), string());
	  parsed_names[n] = name;
	  parsed_nums[name] = n;
	}
	    
	parsed.push_back( SQLParseElement(str,option,n) );
	str = "";
	name = "";
      } else {
	str += '%';
      }
    } else {
      str += *s++;
    }
  }
  parsed.push_back( SQLParseElement(str,' ',-1) );
  delete[] s0;
}

Added sqlplusint/sql_query0.hh.












































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __sql_query0_hh__
#define __sql_query0_hh__

#define mysql_query_define0(RETURN, FUNC)\
  RETURN FUNC (ss a)\
    {return FUNC (parms() << a);}\
  RETURN FUNC (ss a, ss b)\
    {return FUNC (parms() << a << b);}\
  RETURN FUNC (ss a, ss b, ss c)\
    {return FUNC (parms() << a << b << c);}\
  RETURN FUNC (ss a, ss b, ss c, ss d)\
    {return FUNC (parms() << a << b << c << d);}\
  RETURN FUNC (ss a, ss b, ss c, ss d, ss e)\
    {return FUNC (parms() << a << b << c << d << e);} \
  RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f)\
    {return FUNC (parms() << a << b << c << d << e << f);}\
  RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g)\
    {return FUNC (parms() << a << b << c << d << e << f << g);}\
  RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)\
    {return FUNC (parms() << a << b << c << d << e << f << g << h);}\
  RETURN FUNC (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
    {return FUNC (parms() << a << b << c << d << e << f << g << h << i);}\
  RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
    {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
  RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
    {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
  RETURN FUNC (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,\
		       ss l)\
    {return FUNC (parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\

#define mysql_query_define_const1(RETURN, FUNC) \
  RETURN FUNC () const {return FUNC (def);} \
  RETURN FUNC (query_reset r) {return FUNC (def,r);} \
  RETURN FUNC (const char* str) const; \
  RETURN FUNC (const parms &p) const; \
  RETURN FUNC (const parms &p, query_reset r);\
  mysql_query_define0(RETURN,FUNC) \

#define mysql_query_define1(RETURN, FUNC) \
  RETURN FUNC (query_reset r = RESET_QUERY) {return FUNC (def,r);} \
  RETURN FUNC (const char* str); \
  RETURN FUNC (parms &p, query_reset r = RESET_QUERY);\
  mysql_query_define0(RETURN,FUNC) \

#define mysql_query_define2(FUNC) \
  template <class T1> void FUNC (T1 &con, query_reset r = RESET_QUERY) {FUNC (con, def,r);} \
  template <class T1> void FUNC (T1 &con, const char* str); \
  template <class T1> void FUNC (T1 &con, parms &p, query_reset r = RESET_QUERY);\
  template <class T1> void FUNC (T1 &con, ss a)\
    {FUNC (con, parms() << a);}\
  template <class T1> void FUNC (T1 &con, ss a, ss b)\
    {FUNC (con, parms() << a << b);}\
  template <class T1> void FUNC (T1 &con, ss a, ss b, ss c)\
    {FUNC (con, parms() << a << b << c);}\
  template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d)\
    {FUNC (con, parms() << a << b << c << d);}\
  template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e)\
    {FUNC (con, parms() << a << b << c << d << e);} \
  template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e, ss f)\
    {FUNC (con, parms() << a << b << c << d << e << f);}\
  template <class T1> void FUNC (T1 &con,ss a,ss b,ss c,ss d,ss e,ss f,ss g)\
    {FUNC (con, parms() << a << b << c << d << e << f << g);}\
  template <class T1> void FUNC (T1 &con,ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h)\
    {FUNC (con, parms() << a << b << c << d << e << f << g << h);}\
  template <class T1> void FUNC (T1 &con, ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)\
    {FUNC (con, parms() << a << b << c << d << e << f << g << h << i);}\
  template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)\
    {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j);}\
  template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)\
    {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k);}\
  template <class T1> void FUNC (T1 &con, ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,\
		       ss l)\
    {FUNC (con, parms() <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l);}\


#endif
Added sqlplusint/sql_query1.hh.






































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __sql_query_1_hh
#define __sql_query_1_hh

#include <strstream.h>
#include <vector>
#include <map>
#include "define_short"
#include "sql_query0.hh"
#include "sql_string1.hh"

class Query;
class SQLQuery;


//! with_class = SQLQuery

//: Exception thrown when not enough parameters are provided
// Thrown when not enough parameters are provided for a 
// template query.
struct SQLQueryNEParms {
  SQLQueryNEParms(const char *c) : error(c) {}
  const char* error; //:
};

//: This class holds the parameter values for filling template queries. 
// It is a subclass of a vector of *SQLStrings*.
class SQLQueryParms : public vector<SQLString> {
  friend Query;
private:
  typedef const SQLString&      ss;
  SQLQuery                 *parent;
public:
  SQLQueryParms () : parent(NULL) {} 
  SQLQueryParms (SQLQuery *p) : parent(p) {}
  bool  bound() {return parent;}
  void               clear() {erase(begin(),end());} //: Clears the list
  SQLString &operator [] (size_type n) {
    if (n >= size()) insert(end(),(n+1) - size(), "");
    return vector<SQLString>::operator [] (n);
  } //: Access element number n
  const SQLString &operator [] (size_type n) const 
    {return vector<SQLString>::operator [] (n);}     
  //: Access element number n
  SQLString &operator [] (const char *str); 
  //: Access the value of the element with a key of str.

  const SQLString &operator [] (const char *str) const; 
  //: Access the value of the element with a key of str.

  SQLQueryParms &operator << (const SQLString &str)
    {push_back(str);return *this;}  //: Adds an element to the list

  SQLQueryParms &operator += (const SQLString &str)
    {push_back(str);return *this;}  //: Adds an element to the list

  SQLQueryParms operator + (const SQLQueryParms &other) const;

  //!dummy: void set (ss a, [ss b] ,... , [ss l]);
  //: Set the elements.
  // Sets element 0 to a, element 1 to b, etc. May specify up to a dozen elements

  void set (ss a)
    {clear(); *this << a;}
  void set (ss a, ss b)
    {clear(); *this << a << b;}
  void set (ss a, ss b, ss c)
    {clear(); *this << a << b << c;}
  void set (ss a, ss b, ss c, ss d)
    {clear(); *this << a << b << c << d;}
  void set (ss a, ss b, ss c, ss d, ss e)
    {clear(); *this << a << b << c << d << e;}
  void set (ss a, ss b, ss c, ss d, ss e, ss f)
    {clear(); *this << a << b << c << d << e << f;}
  void set (ss a, ss b, ss c, ss d, ss e, ss f, ss g)
    {clear(); *this << a << b << c << d << e << f << g;}
  void set (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)
    {clear(); *this << a << b << c << d << e << f << g << h;}
  void set (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)
    {clear(); *this << a << b << c << d << e << f << g << h << i;}
  void set (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j)
    {clear(); *this <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j;}
  void set (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k)
    {clear(); *this <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k;}
  void set (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k,ss l)
    {clear(); *this <<a <<b <<c <<d <<e <<f <<g <<h <<i <<j <<k <<l;}
};

//:
enum query_reset {DONT_RESET, RESET_QUERY};

struct SQLParseElement {
  SQLParseElement(string b, char o, char n) : before(b),option(o),num(n) {}
  string before;
  char   option;
  char   num;
};

//! with_class = Query

//: The "pure" query class 

// This is the "pure" query class. It is used to form queries to send
// to the *Connection* object. The *Query* class can be used if you
// wish to also be able to execute the queries without having to send
// them to the *Connection* object.
//
// This class is subclassed from *strstream*. This means that you can
// write to it like a stream to avoid having to piece parts together
// by creating you own *strstream* or by using *sprintf*. Although you
// can read from query because it is a stream this is _not_
// recommended. I can not guarantee the predictability of the class if
// you do and will offer no help if you run into problems when you do
// this. However, fell free to use any of the stream methods to write
// to it. Just make sure that the write buffer points to the end of
// your query before you try to use any of the *SQLQuery* specific
// methods except for *error()* and *success()*.

class SQLQuery : public strstream { 
  friend SQLQueryParms; 
private:
  char* preview_char();
protected:
  bool    Success;
  char*   errmsg;
  vector<SQLParseElement> parsed;
  vector<string>          parsed_names;
  map<string,int>         parsed_nums;
  typedef  const SQLString&  ss;
  typedef  SQLQueryParms  parms;
  void     proc(parms &p);

public:
  SQLQuery(): Success(false), errmsg(NULL), def(this) {} //:
  SQLQuery(const SQLQuery &q); //:
  SQLQuery& operator = (const SQLQuery &q); //:

  SQLQueryParms def; //: The default template parameters set. 

  void     parse();  

  string   error () const {return errmsg;}
  bool     success() const {return Success;}

  operator bool () {return success();}
  bool operator !    () {return !success();}

  //!dummy: string str (query_reset r = DONT_RESET);
  //: Returns the full query string.
  // Returns the full query string, replacing it with the default
  // template parameters if necessary. *query_reset* can either be
  // DONT_RESET or RESET_QUERY. If it is set the RESET_QUERY then
  // reset() is called after it has finished returning the query. If
  // there is not enough  parameters then it will return a
  // empty string and *success()* would be false.

  //!dummy: string str (const SQLString &parm0, ...,const SQLString &parm11);
  //: Like str(query_reset) but sets the parameters.
  // Like str(query_reset) but sets query parameters 0 to (up to)
  // 11. To parm0, parm1 etc. This is archived by overloaded methods
  // and templates and not the ...
  //
  // It will combine this with def. If any of the required parameters
  // are null it will produce an error and return an empty string.

  //!dummy: string str(const SQLQueryParms & p, query_reset r = DONT_RESET);
  //: Like *str(query_reset)* but sets the parameter.
  // Like *query(query_reset res)* but sets the parameters based on
  // combining p and def.
  //
  // If any of the required parameters are null it will produce an
  // error and return an empty string.

  void     reset (); //: Resets the query. 
  // This means erasing the string and the default template parameters. 

  template <class T> SQLQuery& update(const T &o, const T &n) {
    reset();
    *this << "UPDATE " << o.table() << " SET " << n.equal_list() 
          << " WHERE " << o.equal_list(" AND ", sql_use_compare);
    return *this;
  } //:
  template <class T> SQLQuery& insert(const T &v) {
    reset();
    *this << "INSERT INTO " << v.table() << " (" << v.field_list()
          << ") VALUES (" << v.value_list() << ")";
    return *this;
  } //:
  template <class T> SQLQuery& replace(const T &v) {
    reset();
    *this << "REPLACE INTO " << v.table() << " (" << v.field_list()
          << ") VALUES (" << v.value_list() << ")";
    return *this;
  } //:

  mysql_query_define_const1(string,str)
};  

#endif
Added sqlplusint/sql_query2.hh.















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __sql_query2_hh__
#define __sql_query2_hh__

#include "sql_query1.hh"

inline SQLString &SQLQueryParms::operator[] (const char *str) {
  if (parent) return operator[] (parent->parsed_nums[str]);
  throw; // only here temporary 
}
inline const SQLString &SQLQueryParms::operator[] (const char *str) const {
  if (parent) return operator[] (parent->parsed_nums[str]);
  throw; // only here temporary 
}

#endif
Added sqlplusint/sql_query3.hh.


1
2
+
+

#include "sql_query2.hh"
Added sqlplusint/sql_string1.hh.


























































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __sql_string1_hh__
#define __sql_string1_hh__

#include <stdio.h>
#include <string>
#include "defs"
#include "define_short"

//: A special string that will convert from anything.
// A class subclassed from string that has the additional ability to
// convert from any valid mysql type.

class SQLString : public string {
public:
  bool is_string;
  bool dont_escape;
  bool processed;

  SQLString() : is_string(false) , processed(false) {}
  SQLString (const string& str) :string (str)
    {is_string=true;processed=false;dont_escape=false;}
  SQLString (const char *str) :string (str) 
    {is_string=true;processed=false;dont_escape=false;}
  SQLString& operator = (const char *str) {
    string::operator = (str); return *this;
  }
  SQLString& operator = (const string& str) {
    string::operator = (str); return *this;
  }
  SQLString (char i) : is_string(false), processed(false)
    {char s[6]; sprintf(s,"%dh",(short int)i); *this=s;}
  SQLString (unsigned char i) : is_string(false), processed(false)
    {char s[6]; sprintf(s,"%uh",(short int)i); *this=s;}
  SQLString (short int i) : is_string(false), processed(false)
    {char s[6]; sprintf(s,"%dh",i); *this=s;}
  SQLString (unsigned short int i) : is_string(false), processed(false)
    {char s[6]; sprintf(s,"%uh",i); *this=s;}
  SQLString (int i) : is_string(false), processed(false)
    {char s[11]; sprintf(s,"%d",i); *this=s;}
  SQLString (unsigned int i) : is_string(false), processed(false)
    {char s[11]; sprintf(s,"%u",i); *this=s;}
/*SQLString (long long int i) : is_string(false), processed(false)
    {char s[22]; sprintf(s,"%dL",i); *this=s;}
  SQLString (unsigned long long int i) : is_string(false), processed(false) 
    {char s[22]; sprintf(s,"%uL",i); *this=s;}
*/
  SQLString (float i) : is_string(false), processed(false)
    {char s[40]; sprintf(s,"%g",i); *this=s;}
  SQLString (double i) : is_string(false), processed(false)
    {char s[40]; sprintf(s,"%g",i); *this=s;}
};

#endif





Added sqlplusint/sql_string2.hh.



1
2
3
+
+
+

#include "sql_string1.hh"

Added sqlplusint/sql_string3.hh.



1
2
3
+
+
+

#include "sql_string2.hh"

Added sqlplusint/sqlplus.hh.









































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "defs"
#include "define_short"

#include "coldata1.hh"
#include "compare1.hh"
#include "connection1.hh"
#include "const_string1.hh"
#include "convert1.hh"
#include "datetime1.hh"
#include "field_names1.hh"
#include "field_types1.hh"
#include "fields1.hh"
#include "manip1.hh"
#include "null1.hh"
#include "query1.hh"
#include "resiter1.hh"
#include "result1.hh"
#include "row1.hh"
#include "set1.hh"
#include "sql_query1.hh"
#include "sql_string1.hh"
#include "stream2string1.hh"
#include "tiny_int1.hh"
#include "type_info1.hh"
#include "vallist1.hh"

#include "coldata2.hh"
#include "compare2.hh"
#include "connection2.hh"
#include "const_string2.hh"
#include "convert2.hh"
#include "datetime2.hh"
#include "field_names2.hh"
#include "field_types2.hh"
#include "fields2.hh"
#include "manip2.hh"
#include "null2.hh"
#include "query2.hh"
#include "result2.hh"
#include "row2.hh"
#include "set2.hh"
#include "sql_query2.hh"
#include "sql_string2.hh"
#include "stream2string2.hh"
#include "tiny_int2.hh"
#include "type_info2.hh"
#include "vallist2.hh"

#include "coldata3.hh"
#include "compare3.hh"
#include "connection3.hh"
#include "const_string3.hh"
#include "convert3.hh"
#include "datetime3.hh"
#include "field_names3.hh"
#include "field_types3.hh"
#include "manip3.hh"
#include "null3.hh"
#include "query3.hh"
#include "result3.hh"
#include "row3.hh"
#include "set3.hh"
#include "sql_query3.hh"
#include "sql_string3.hh"
#include "stream2string3.hh"
#include "tiny_int3.hh"
#include "type_info3.hh"
#include "vallist3.hh"

#ifdef MYSQL_NO_SHORT_NAMES
#include "undef_short"
#endif
Added sqlplusint/stream2string1.hh.







1
2
3
4
5
6
7
+
+
+
+
+
+
+
#ifndef __stream2string1_hh__
#define __stream2string1_hh__

template<class Strng, class T>
Strng stream2string(const T &object);

#endif
Added sqlplusint/stream2string2.hh.


1
2
+
+

#include "stream2string1.hh"
Added sqlplusint/stream2string3.hh.





















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __stream2string3_hh__
#define __stream2string3_hh__

#include <strstream.h>

template<class Strng, class T>
Strng stream2string(const T &object) {
  ostrstream str;
  object.out_stream(str);
  str << ends;
  Strng s = str.str();
#ifdef __USLC__
  strstreambuf *tmpbuf = str.rdbuf();
  tmpbuf->freeze(0);
#else
  str.freeze(0);
#endif
  return s;
}

#endif
Added sqlplusint/tiny_int1.hh.






































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __tiny_int1_hh__
#define __tiny_int1_hh__

class tiny_int {
  char value;
public:
  tiny_int() {}
  tiny_int(short int v) : value(v) {}
  operator short int() const {return (short int)value;};
  tiny_int &operator = (short int v) {value=v; return *this;}
  tiny_int &operator += (short int v) {value+=v; return *this;}
  tiny_int &operator -= (short int v) {value-=v; return *this;}
  tiny_int &operator *= (short int v) {value*=v; return *this;}
  tiny_int &operator /= (short int v) {value/=v; return *this;}
  tiny_int &operator %= (short int v) {value%=v; return *this;}
  tiny_int &operator &= (short int v) {value&=v; return *this;}
  tiny_int &operator |= (short int v) {value|=v; return *this;}
  tiny_int &operator ^= (short int v) {value^=v; return *this;}
  tiny_int &operator <<= (short int v) {value<<=v; return *this;}
  tiny_int &operator >>= (short int v) {value>>=v; return *this;}
  tiny_int &operator ++ () {value++; return *this;}
  tiny_int &operator -- () {value--; return *this;}
  tiny_int operator ++ (int) {tiny_int tmp=value; value++; return tmp;}
  tiny_int operator -- (int) {tiny_int tmp=value; value--; return tmp;}
  tiny_int operator - (const tiny_int& i) const {return value - i;}
  tiny_int operator + (const tiny_int& i) const {return value + i;}
  tiny_int operator * (const tiny_int& i) const {return value * i;}
  tiny_int operator / (const tiny_int& i) const {return value / i;}
  tiny_int operator % (const tiny_int& i) const {return value % i;}
  tiny_int operator | (const tiny_int& i) const {return value | i;}
  tiny_int operator & (const tiny_int& i) const {return value & i;}
  tiny_int operator ^ (const tiny_int& i) const {return value ^ i;}
  tiny_int operator << (const tiny_int& i) const {return value << i;}
  tiny_int operator >> (const tiny_int& i) const {return value >> i;}
};


#endif
Added sqlplusint/tiny_int2.hh.



1
2
3
+
+
+

#include "tiny_int1.hh"

Added sqlplusint/tiny_int3.hh.



1
2
3
+
+
+

#include "tiny_int2.hh"

Added sqlplusint/tracker.h.

























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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#ifndef __mysql_tracker_h__
#define __mysql_tracker_h__

#include <set.h>
#include <map.h>

template <class Pointer, class Object> 
class pointer_tracker {
private:
  map<Pointer*, set<Object*> > tracker;
public:
  void insert (Pointer *p, Object *o) {
    tracker[p].insert(o);
  }
  void remove (Pointer *p, Object *o) {
    tracker[p].erase(o); 
    if (tracker[p].empty()) {
      tracker.erase(p);
      o->purge(p);
    }
  }
};

#endif
Added sqlplusint/type_info.cc.


































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#endif
#include <mysql.h>
#include <string.h>
#include "datetime1.hh"
#include "set1.hh"
#include "type_info3.hh"

typedef string Enum;

const mysql_type_info::sql_type_info mysql_type_info::types[62] = {
  sql_type_info("DECIMAL NOT NULL", typeid(double), 0),
  sql_type_info("TINYINT NOT NULL", typeid(signed char), 1, true),
  sql_type_info("SMALLINT NOT NULL", typeid(short int), 2, true),
  sql_type_info("INT NOT NULL", typeid(int), 3, true),
  sql_type_info("FLOAT NOT NULL", typeid(float), 4, true),
  sql_type_info("DOUBLE NOT NULL", typeid(double), 5, true),
  sql_type_info("NULL NOT NULL", typeid(void), 6),
  sql_type_info("TIMESTAMP NOT NULL", typeid(Time), 7),
  sql_type_info("BIGINT NOT NULL", typeid(long long int), 8, true),
  sql_type_info("MEDIUMINT NOT NULL", typeid(int), 9),
  sql_type_info("DATE NOT NULL", typeid(Date), 10, true),
  sql_type_info("TIME NOT NULL", typeid(Time), 11, true),
  sql_type_info("DATETIME NOT NULL", typeid(DateTime), 12, true),
  sql_type_info("ENUM NOT NULL", typeid(Enum), 13, true),
  sql_type_info("SET NOT NULL", typeid(Set<string>), 14, true),
  sql_type_info("TINYBLOB NOT NULL", typeid(string), 15),
  sql_type_info("MEDIUMBLOB NOT NULL", typeid(string), 16),
  sql_type_info("LONGBLOB NOT NULL", typeid(string), 17),
  sql_type_info("BLOB NOT NULL", typeid(string), 18),
  sql_type_info("VARCHAR NOT NULL", typeid(string), 19, true),
  sql_type_info("CHAR NOT NULL", typeid(string), 20),
  sql_type_info("CHAR NOT NULL", typeid(string), 21),
  sql_type_info("TINYINT UNSIGNED NOT NULL", typeid(unsigned char), 22, true),
  sql_type_info("SMALLINT UNSIGNED NOT NULL", typeid(unsigned short int), 23, true),
  sql_type_info("INT UNSIGNED NOT NULL", typeid(unsigned int), 24, true),
  sql_type_info("INT UNSIGNED NOT NULL", typeid(unsigned int), 25, true),
  sql_type_info("INT UNSIGNED NOT NULL", typeid(unsigned int), 26, true),
  sql_type_info("INT UNSIGNED NOT NULL", typeid(unsigned int), 27, true),
  sql_type_info("INT UNSIGNED NOT NULL", typeid(unsigned int), 28, true),
  sql_type_info("BIGINT UNSIGNED NOT NULL", typeid(unsigned long long int), 29, true),
  sql_type_info("MEDIUMINT UNSIGNED NOT NULL", typeid(unsigned int), 30),

  sql_type_info("DECIMAL NULL", typeid(Null<double>), 0),
  sql_type_info("TINYINT NULL", typeid(Null<signed char>), 1, true),
  sql_type_info("SMALLINT NULL", typeid(Null<short int>), 2, true),
  sql_type_info("INT NULL", typeid(Null<int>), 3, true),
  sql_type_info("FLOAT NULL", typeid(Null<float>), 4, true),
  sql_type_info("DOUBLE NULL", typeid(Null<double>), 5, true),
  sql_type_info("NULL NULL", typeid(Null<void>), 6),
  sql_type_info("TIMESTAMP NULL", typeid(Null<Time>), 7),
  sql_type_info("BIGINT NULL", typeid(Null<long long int>), 8, true),
  sql_type_info("MEDIUMINT NULL", typeid(Null<int>), 9), 
  sql_type_info("DATE NULL", typeid(Null<Date>), 10, true),
  sql_type_info("TIME NULL", typeid(Null<Time>), 11, true),
  sql_type_info("DATETIME NULL", typeid(Null<DateTime>), 12, true),
  sql_type_info("ENUM NULL", typeid(Null<Enum>), 13, true),
  sql_type_info("SET NULL", typeid(Null<Set<string> >), 14, true),
  sql_type_info("TINYBLOB NULL", typeid(Null<string>), 15),
  sql_type_info("MEDIUMBLOB NULL", typeid(Null<string>), 16),
  sql_type_info("LONGBLOB NULL", typeid(Null<string>), 17),
  sql_type_info("BLOB NULL", typeid(Null<string>), 18),
  sql_type_info("VARCHAR NULL", typeid(Null<string>), 19, true),
  sql_type_info("CHAR NULL", typeid(Null<string>), 20),
  sql_type_info("CHAR NULL", typeid(Null<string>), 21),
  sql_type_info("TINYINT UNSIGNED NULL", typeid(Null<unsigned char>), 22, true),
  sql_type_info("SMALLINT UNSIGNED NULL", typeid(Null<unsigned short int>),23, true),
  sql_type_info("INT UNSIGNED NULL", typeid(Null<unsigned int>), 24, true),
  sql_type_info("INT UNSIGNED NULL", typeid(Null<unsigned int>), 25, true),
  sql_type_info("INT UNSIGNED NULL", typeid(Null<unsigned int>), 26, true),
  sql_type_info("INT UNSIGNED NULL", typeid(Null<unsigned int>), 27, true),
  sql_type_info("INT UNSIGNED NULL", typeid(Null<unsigned int>), 28, true),
  sql_type_info("BIGINT UNSIGNED NULL", typeid(Null<unsigned long long int>),29, true),
  sql_type_info("MEDIUMINT UNSIGNED NULL", typeid(Null<unsigned int>), 30),
};

const mysql_type_info::sql_type_info_lookup 
  mysql_type_info::lookups(mysql_type_info::types, 62);

mysql_ti_sql_type_info_lookup::
mysql_ti_sql_type_info_lookup(const sql_type_info types[], const int size) {
  for (int i = 0; i != size; i++) {
    if (types[i]._default)
      _map[types[i]._c_type] = i;
  }
}

unsigned char mysql_type_info::type(enum_field_types t, 
			              bool _unsigned, bool _null) {
  if (_null) {
    if (_unsigned) {
      return unsigned_null_offset + t;
    } else {
      if (t < 200) return null_offset + t;
      else return null_offset + (t-234);
    }
  } else {
    if (_unsigned) {
      return unsigned_offset + t;
    } else {
      if (t < 200) return offset + t;
      else return offset + (t-234);
    }
  }
}

bool mysql_type_info::quote_q() const {
  if (base_type().c_type() == typeid(string) ||
      base_type().c_type() == typeid(Date) ||
      base_type().c_type() == typeid(Time) ||
      base_type().c_type() == typeid(DateTime) ||
      base_type().c_type() == typeid(Enum) ||
      base_type().c_type() == typeid(Set<string>)) 
    {
      return true;
    } else {
      return false;
    }
}

bool mysql_type_info::escape_q() const {
  if (c_type() == typeid(string)) 
    return true;
  else 
    return false;
}
Added sqlplusint/type_info1.hh.


































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __type_info1_hh__
#define __type_info1_hh__
#ifdef __WIN32__
#include <Windows32/Base.h>
#include <Windows32/Defines.h>
#include <Windows32/Structures.h>
#include <winsock.h>
#define errno WSAGetLastError()
#endif
#include <mysql.h>
#include <typeinfo>
#include <map>

#ifdef __USLC__
using namespace std;
#endif

class mysql_type_info;
class mysql_ti_sql_type_info_lookup;

class mysql_ti_sql_type_info {
  friend mysql_type_info;
  friend mysql_ti_sql_type_info_lookup;
private:
  const char          *_sql_name;
  const type_info     *_c_type;
  const unsigned char  _base_type;
  const bool           _default;
  mysql_ti_sql_type_info (const mysql_ti_sql_type_info &b);           // can't do
  mysql_ti_sql_type_info& operator=(const mysql_ti_sql_type_info &b); //  "    "
  mysql_ti_sql_type_info () {} 
  // OEP - didn't init _base_type and _default mysql_ti_sql_type_info () {} 
  // all private, only mysql_type_info can
  // create because there *must* be only one copy
  // of each.
  mysql_ti_sql_type_info (const char *s, const type_info &t, 
			  const unsigned char bt = 0,  const bool d = false )
    : _sql_name(s), _c_type(&t), _base_type(bt), _default(d) {}
};

struct type_info_cmp {
  bool operator() (const type_info *lhs, const type_info *rhs) const {
    return lhs->before(*rhs);
  }
};

class mysql_ti_sql_type_info_lookup {
  friend mysql_type_info;
private:
  typedef mysql_ti_sql_type_info sql_type_info;

  map<const type_info *, unsigned char, type_info_cmp> _map;
  
  mysql_ti_sql_type_info_lookup(const sql_type_info types[], const int size);

  const unsigned char& operator [] (const type_info &ti) const {
    return _map.find(&ti)->second;
  }
};

//: Class that holds basic type information for ColData.
class mysql_type_info {
private:
  typedef mysql_ti_sql_type_info sql_type_info;
  typedef mysql_ti_sql_type_info_lookup sql_type_info_lookup;
private:
  static const sql_type_info types[62];
  
  static const unsigned char offset = 0;
  static const unsigned char unsigned_offset = 21; 
  static const unsigned char null_offset = 31;
  static const unsigned char unsigned_null_offset = 52;

  static const sql_type_info_lookup lookups;
  
  static unsigned char type(enum_field_types t,
			      bool _unsigned, bool _null = false);
public:
  static const unsigned char string_type = 20;
private:
  unsigned char num;
	unsigned int _length;
	unsigned int _max_length;
  inline const sql_type_info& deref() const;
public:
  //!dummy: static const unsigned char string_type;
  //: The id of the string type.
  mysql_type_info() {} //:
  mysql_type_info(unsigned char n) : num(n) {} //:
  inline mysql_type_info(enum_field_types t,
			 bool _unsigned, bool _null);
  //:
  inline mysql_type_info(const MYSQL_FIELD &f);
  //:
  mysql_type_info(const mysql_type_info &t) : num(t.num) {}
  //:
  mysql_type_info(const type_info &t) {num = lookups[t]; }
  //: 
  mysql_type_info& operator = (unsigned char n) {num=n; return *this;}
  //:
  mysql_type_info& operator = (const mysql_type_info &t) 
    {num = t.num; return *this;}
  //:
  mysql_type_info& operator = (const type_info &t)
    {num = lookups[t]; return *this;}
  //:
  inline const char*           name()      const;
  //: Returns a implication defined name of the c++ type.
  // Returns the name that would be returned by typeid().name() for the C++ type
  // associated with the sql type.
  inline const char*           sql_name()  const;
  //: Returns the name for the sql type.
  inline const type_info&      c_type()    const;
	inline const unsigned int length() const;
	inline const unsigned int max_length() const;
  //: Returns the type_info for the C++ type associated with the sql type.
  inline const mysql_type_info base_type() const;
  //: Returns the type_info for the C++ type inside of the Null type.
  // If the type is not null then this is the same as c_type() 
         int                   id()        const {return num;}
  //: Returns the id of the sql_type.
  // Note: Do not ever use this id directly as it may change between versions.

  bool quote_q()  const;
  //: Returns true if the sql type is of a type that needs to be quoted.
  bool escape_q() const;
  //: Returns true if the sql type is of a type that needs to be escaped.
  
  bool before(mysql_type_info &b) { return num < b.num; }
  //: Provides ordering
  // You can also use id() for the same purpose.
};

inline const mysql_type_info::sql_type_info& mysql_type_info::deref() const {
  return types[num];
}
inline const char*           mysql_type_info::name()      const {
  return deref()._c_type->name();
}
inline const char*           mysql_type_info::sql_name()  const {
  return deref()._sql_name;
}
inline const unsigned int    mysql_type_info::length()  const {
  return _length;
}
inline const unsigned int    mysql_type_info::max_length()  const {
  return _max_length;
}
inline const type_info&      mysql_type_info::c_type()    const {
  return *deref()._c_type;
}
inline const mysql_type_info mysql_type_info::base_type() const 
{
  return mysql_type_info(deref()._base_type);
}

inline mysql_type_info::mysql_type_info(enum_field_types t,
					bool _unsigned, bool _null) {
  num = type(t,_unsigned,_null);
}

inline mysql_type_info::mysql_type_info(const MYSQL_FIELD &f) {
  num = type(f.type, (f.flags & UNSIGNED_FLAG), !(f.flags & NOT_NULL_FLAG));
	_length = f.length; _max_length = f.max_length;
}

inline bool operator == (const mysql_type_info& a, const mysql_type_info& b) {
  return a.id() == b.id();
}

inline bool operator != (const mysql_type_info& a, const mysql_type_info& b) {
  return a.id() != b.id();
}

inline bool operator == (const type_info &a, const mysql_type_info &b) {
  return a == b.c_type();
}

inline bool operator != (const type_info &a, const mysql_type_info &b) {
  return a != b.c_type();
}

inline bool operator == (const mysql_type_info &a, const type_info &b) {
  return a.c_type() == b;
}

inline bool operator != (const mysql_type_info &a, const type_info &b) {
  return a.c_type() != b;
}


#endif


Added sqlplusint/type_info2.hh.



1
2
3
+
+
+

#include "type_info1.hh"

Added sqlplusint/type_info3.hh.



1
2
3
+
+
+

#include "type_info2.hh"

Added sqlplusint/vallist.cc.






















































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include "vallist3.hh"
#include "row2.hh"

void create_vector(int size, vector<bool>& v, bool t0, 
		   bool t1, bool t2, bool t3, bool t4,
		   bool t5, bool t6, bool t7, bool t8,
		   bool t9, bool ta, bool tb, bool tc)
{
  v.reserve(size);
  v.push_back(t0); if (size == 1) return;
  v.push_back(t1); if (size == 2) return;
  v.push_back(t2); if (size == 3) return;
  v.push_back(t3); if (size == 4) return;
  v.push_back(t4); if (size == 5) return;
  v.push_back(t5); if (size == 6) return;
  v.push_back(t6); if (size == 7) return;
  v.push_back(t7); if (size == 8) return;
  v.push_back(t8); if (size == 9) return;
  v.push_back(t9); if (size == 10) return;
  v.push_back(ta); if (size == 11) return;
  v.push_back(tb); if (size == 12) return;
  v.push_back(tc);
}

template <class Container>
void create_vector(const Container&c, vector<bool>&v, string s0, string s1, 
		   string s2, string s3, string s4, string s5, string s6,
		   string s7, string s8, string s9, string sa, string sb,
		   string sc)
{
  v.insert(v.begin(), c.size(), false);
  v[c.parent().field_num(s0)] = true; if (s1.empty()) return;
  v[c.parent().field_num(s1)] = true; if (s2.empty()) return;
  v[c.parent().field_num(s2)] = true; if (s3.empty()) return;
  v[c.parent().field_num(s3)] = true; if (s4.empty()) return;
  v[c.parent().field_num(s4)] = true; if (s5.empty()) return;
  v[c.parent().field_num(s5)] = true; if (s6.empty()) return;
  v[c.parent().field_num(s6)] = true; if (s7.empty()) return;
  v[c.parent().field_num(s7)] = true; if (s8.empty()) return;
  v[c.parent().field_num(s8)] = true; if (s9.empty()) return;
  v[c.parent().field_num(s9)] = true; if (sa.empty()) return;
  v[c.parent().field_num(sa)] = true; if (sb.empty()) return;
  v[c.parent().field_num(sb)] = true; if (sc.empty()) return;
  v[c.parent().field_num(sc)] = true;
}

template void create_vector (const Row &c, vector<bool>&v, string s0, string s1, 
		   string s2, string s3, string s4, string s5, string s6,
		   string s7, string s8, string s9, string sa, string sb,
		   string sc);

template void create_vector (const MutableRow<ResUse> &c, vector<bool>&v, string s0, string s1, 
		   string s2, string s3, string s4, string s5, string s6,
		   string s7, string s8, string s9, string sa, string sb,
		   string sc);

template void create_vector (const MutableRow<MutableRes> &c, vector<bool>&v, string s0, string s1, 
		   string s2, string s3, string s4, string s5, string s6,
		   string s7, string s8, string s9, string sa, string sb,
		   string sc);

/*
int main() {
  const char *x[8] = {"12","11","This is a", "9","7","6","5","4"};
  cout << "Compile Good\n";
  simp_list_b<const char **> X(x,x+8);
  cout << *X.begin() << endl;
  cout << value_list(X) << endl;
  cout << value_list(X,";") << endl;
  vector<char *> xx;
  xx.push_back("testing");
  xx.push_back("I want you now");
  xx.push_back("Whats the deal man");
  cout << value_list(xx,",",quote) << endl;
  cout << value_list(xx,";") << endl;
  vector<const char *> xy;
  xy.push_back("test");
  xy.push_back("want");
  xy.push_back("deal");
  cout << "V1: " << value_list(xy,",",quote,true,false,true) << endl;
  cout << "V2: " << value_list(xy,",",quote,true,true,true) << endl;
  cout << "V3: " << value_list(xy,";") << endl;
  cout << "EL: " << equal_list(xy,xx) << endl;
  cout << "EL: " << equal_list(xy,xx, " AND ", " > ", quote,true,false,true) << endl;
}
*/
Added sqlplusint/vallist1.hh.






























































































































































































































































































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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#ifndef __vallist1_hh__
#define __vallist1_hh__

#include <string>
#include <vector>
#include "manip1.hh"

template <class Seq, class Manip>
struct value_list_b {
  const Seq          *list;
  const vector<bool> fields;
  const char         *delem;
  Manip              manip;
  value_list_b(const Seq &s, const vector<bool> &f, const char *d, Manip m) 
    : list(&s), fields(f), delem(d), manip(m) {}
};

template <class Seq1, class Seq2, class Manip>
struct equal_list_b {
  const Seq1         *list1;
  const Seq2         *list2;
  const vector<bool> fields;
  const char         *delem;
  const char         *equl;
  Manip              manip;
  equal_list_b(const Seq1 &s1, const Seq2 &s2, const vector<bool> &f,
	       const char *d, const char *e, Manip m) 
    : list1(&s1), list2(&s2), fields(f), delem(d), equl(e), manip(m) {}
};

template <class Seq, class Manip>
struct value_list_ba {
  const Seq          *list;
  const char         *delem;
  Manip              manip;
  value_list_ba(const Seq &s, const char* d, Manip m) 
    : list(&s), delem(d), manip(m) {}
};

template <class Seq1, class Seq2, class Manip>
struct equal_list_ba {
  const Seq1         *list1;
  const Seq2         *list2;
  const char         *delem;
  const char         *equl;
  Manip              manip;
  equal_list_ba(const Seq1 &s1, const Seq2 &s2, const char *d, const char *e,
		Manip m) 
    : list1(&s1), list2(&s2), delem(d), equl(e), manip(m) {}
};

//

template <class Seq, class Manip>
ostream& operator << (ostream &o, const value_list_b<Seq, Manip> &cl) {
  typename Seq::const_iterator i =  cl.list->begin();
  register int k = 0;
  for (;;) {
    if (cl.fields[k])
      o << cl.manip << *i;
    k++;
    if (++i == cl.list->end()) break;
    if (cl.fields[k])
      o << cl.delem;
  }
  return o;
}

template <class Seq1, class Seq2, class Manip>
ostream& operator << (ostream &o, const equal_list_b<Seq1, Seq2, Manip> &el) {
  typename Seq1::const_iterator i = el.list1->begin();
  typename Seq2::const_iterator j = el.list2->begin();
  register int k = 0;
  for (;;) {
    if (el.fields[k]) 
      o << *i << el.equl << el.manip << *j;
    k++;
    j++;
    if (++i == el.list1->end()) break;
    if (el.fields[k])
      o << el.delem;
  }
  return o;
}

template <class Seq, class Manip>
ostream& operator << (ostream &o, const value_list_ba<Seq, Manip> &cl) {
  typename Seq::const_iterator i =  cl.list->begin();
  for (;;) {
    o << cl.manip << *i;
    if (++i == cl.list->end()) break;
    o << cl.delem;
  }
  return o;
}

template <class Seq1, class Seq2, class Manip>
ostream& operator << (ostream &o, const equal_list_ba<Seq1, Seq2, Manip> &el) {
  typename Seq1::const_iterator i = el.list1->begin();
  typename Seq2::const_iterator j = el.list2->begin();
  for (;;) {
    o << *i << el.equl << el.manip << *j;
    j++;
    if (++i == el.list1->end()) break;
    o << el.delem;
  }
  return o;
}

template <class Iter>
class simp_list_b {
public:
  Iter _begin;
  Iter _end;
public:
  typedef Iter const_iterator;
  simp_list_b(Iter b, Iter e) : _begin(b), _end(e) {}
  Iter begin() const {return _begin;}
  Iter end() const {return _end;}
};

//
// create vector
//

void create_vector(int size, vector<bool>& v, bool t0, 
		   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
		   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
		   bool t9=false, bool ta=false, bool tb=false, bool tc=false);

template <class Container>
void create_vector(const Container&c, vector<bool>&v, string s0, string s1, 
		   string s2, string s3, string s4, string s5, string s6,
		   string s7, string s8, string s9, string sa, string sb,
		   string sc);

//
// value list
//

template <class Seq>  
inline
value_list_ba<Seq,do_nothing_type0> 
value_list(const Seq &s, const char *d = ",") {
  return value_list_ba<Seq ,do_nothing_type0> (s, d, do_nothing);
}

template <class Seq, class Manip>  
inline
value_list_ba<Seq,Manip> 
value_list(const Seq &s, const char *d, Manip m) {
  return value_list_ba<Seq,Manip> (s, d, m);
}

template <class Seq, class Manip>
inline
value_list_b<Seq,Manip>
value_list(const Seq &s, const char *d, Manip m, const vector<bool> &vb)
{
  return value_list_b<Seq, Manip>(s, vb, d, m);
}

template <class Seq, class Manip>
value_list_b<Seq,Manip>
value_list(const Seq &s, const char *d, Manip m, bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return value_list_b<Seq, Manip>(s, vb, d, m);
}

template <class Seq>
value_list_b<Seq,do_nothing_type0>
value_list(const Seq &s, const char *d, bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return value_list_b<Seq, do_nothing_type0> (s, vb, d, do_nothing);
}

template <class Seq>
value_list_b<Seq,do_nothing_type0>
value_list(const Seq &s, bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return value_list_b<Seq, do_nothing_type0> (s, vb, ",",do_nothing);
}

//
// equal list
//

template <class Seq1, class Seq2>  
inline
equal_list_ba<Seq1,Seq2,do_nothing_type0> 
equal_list(const Seq1 &s1, const Seq2 &s2, const char *d = ",", 
	   const char *e = " = ") {
  return equal_list_ba<Seq1,Seq2,do_nothing_type0> (s1, s2, d, e, do_nothing);
}

template <class Seq1, class Seq2, class Manip>
inline
equal_list_ba<Seq1,Seq2,Manip> 
equal_list(const Seq1 &s1, const Seq2 &s2, 
	   const char *d, const char *e, Manip m) {
  return equal_list_ba<Seq1,Seq2,Manip> (s1, s2, d, e, m);
}

template <class Seq1, class Seq2, class Manip>
inline
equal_list_b<Seq1, Seq2, Manip>
equal_list(const Seq1 &s1, const Seq2 &s2, const char *d, const char *e, 
	   Manip m, const vector<bool> &vb)
{
  return equal_list_b<Seq1,Seq2,Manip>(s1, s2, vb, d, e, m);
}

// complete
template <class Seq1, class Seq2, class Manip>
equal_list_b<Seq1, Seq2, Manip>
equal_list(const Seq1 &s1, const Seq2 &s2, const char *d, const char *e, 
	   Manip m, bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s1.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return equal_list_b<Seq1,Seq2,Manip>(s1, s2, vb, d, e, m);
}

// delem, equl
template <class Seq1, class Seq2>
equal_list_b<Seq1, Seq2, do_nothing_type0>
equal_list(const Seq1 &s1, const Seq2 &s2, const char *d, const char *e, 
	   bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s1.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return equal_list_b<Seq1,Seq2,do_nothing_type0>
    (s1, s2, vb, d, e, do_nothing);
}

// delem
template <class Seq1, class Seq2>
equal_list_b<Seq1,Seq2,do_nothing_type0>
equal_list(const Seq1 &s1, const Seq2 &s2, const char *d, bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s1.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return equal_list_b<Seq1,Seq2,do_nothing_type0> 
    (s1, s2, vb, d, " = ", do_nothing);
}

// nothing
template <class Seq1, class Seq2>
equal_list_b<Seq1,Seq2,do_nothing_type0>
equal_list(const Seq1 &s1, const Seq2 &s2, bool t0, 
	   bool t1=false, bool t2=false, bool t3=false, bool t4=false,
	   bool t5=false, bool t6=false, bool t7=false, bool t8=false,
	   bool t9=false, bool ta=false, bool tb=false, bool tc=false)
{
  vector<bool> vb;
  create_vector(s1.size(), vb, t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc);
  return equal_list_b<Seq1,Seq2,do_nothing_type0> 
    (s1, s2, vb,"," ," = " ,do_nothing);
}

#endif

Added sqlplusint/vallist2.hh.



1
2
3
+
+
+

#include "vallist1.hh"

Added sqlplusint/vallist3.hh.



1
2
3
+
+
+

#include "vallist2.hh"