Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From 28ea4537fdd6c6f5 To 4ed7917bb6a45ecc
2017-07-02
| ||
00:34 | Assorted tweaks to HACKERS.md. check-in: 00b2c6c61f user: tangent tags: trunk | |
00:25 | Added a link to the Fossil Quick Start guide to our HACKERS.md file check-in: 4ed7917bb6 user: tangent tags: trunk | |
00:24 | Added links to the official Fossil binaries and to the build-from-source instructions in the Fossil project's wiki. check-in: a652f8068d user: tangent tags: trunk | |
2005-08-18
| ||
17:21 | Version 2.0.2 check-in: a7f87157d6 user: tangent tags: trunk, v2.0.2 | |
2005-08-17
| ||
19:48 | Version 2.0.1 check-in: 28ea4537fd user: tangent tags: trunk, v2.0.1 | |
2005-08-16
| ||
18:53 | Version 2.0.0 check-in: 4e4a7fc46f user: tangent tags: trunk, v2.0.0 | |
Added Bakefiles.bkgen.
> > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?xml version="1.0" ?> <bakefile-gen xmlns="http://www.bakefile.org/schema/bakefile-gen"> <input> ./mysql++.bkl </input> <!-- List of output formats to generate: --> <add-formats> autoconf,mingw,msvs2003prj,msvs2005prj,msvs2008prj,xcode2 </add-formats> <add-flags formats="mingw"> -o$(INPUT_FILE_DIR)/Makefile.mingw </add-flags> <add-flags formats="msvs2003prj"> -ovc2003/mysql++.sln </add-flags> <add-flags formats="msvs2005prj"> -ovc2005/mysql++.sln </add-flags> <add-flags formats="msvs2008prj"> -ovc2008/mysql++.sln -DMSVS_PLATFORMS=win64 </add-flags> </bakefile-gen> |
Deleted COPYING.
|
| < < < < < < < < < < |
Added COPYING.txt.
> > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 | 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.txt. 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.txt. |
Deleted CREDITS.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added CREDITS.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 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@foursquare.net>: Lots of GCC warning fixes for the bleeding-edge compiler versions, Gentoo ebuild support, and misc other fixes. 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 examples/multiquery.cpp 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> of Switchplane, Ltd. created the ScopedConnection class, came up with the original idea for Query's for_each() and store_in() methods, provided the basis for examples/for_each.cpp, and provided a fix for exception flag propagation in Query. Jim Wallace <jwallace@kaneva.com> demonstrated the need for BadQuery::errnum(), and contributed the patches and also examples/deadlock.cpp to test that this feature does what it is supposed to. Jonathan Wakely <mysql@kayari.org> rebuilt my original versions of ConnectionPool, RefCountedPointer, and RefCountedBuffer. They're now simpler and safer. He also created the numeric conversion logic in lib/mystring.h introduced in v3.0. Adrian Cornish <mysql@bluedreamer.com> Several fixes and additions. Rick Gutleber <rgutleber@above.net> contributed the Query::insertfrom() method and associated InsertPolicy object, as well as the SQLStream class. 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 | 2.0.1, 2005.08.17 (r1046) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 3.2.3, 2016.12.29 (r2790) o Now using snprintf() instead of _snprintf() on Visual C++ 2015. o Cygwin changed its naming for the MySQL C API library since the last time we successfully tried building MySQL++ there. Reworked the autoconf detection macro to make it less dependent on such individual platform differences. The macro is in fact now entirely side-effect-free, just setting MYSQL_C_* variables that the top-level Bakefile uses when and as it needs them, rather than expecting that major variables like CPPLFAGS and LIBS were overridden by the autoconf macro. This makes the autoconf case more like that of the non-autoconf Bakefile outputs. o Squished a Clang warning 3.2.2, 2015.03.18 (r2780) o The DBDriver::operator= would leak a live connection if you assigned a disconnected DBDriver to it. Patch by Quentin Armitage. o Plugged a potential DBDriver instance leak in Connection ctor. Patch by Yury Alekseev. o Explicitly #including algorithm.h in examples/multiquery.cpp for std::max(). o Added missing "break;" statements in Transaction ctor taking an isolation level parameter, which caused only the last one to do the right thing. Problem noticed by Tony Whyman, fix by me. o The bootstrap script now checks for the existence of needed build tools before trying to use them. This lets us emit a clearer error message than the shell will. Original patch by Adrian Cornish. o Fixed a build problem related to std::min/max with Visual C++ 2013 due to a change in the definitions provided by its header files. o Tracked several changes made to Connector/C made since 3.2.1. o Assorted documentation updates. o Generating HTML with UTF-8 encoding, not 8859-1 3.2.1, 2013.12.10 (r2756) o Connection copy ctor wasn't copying the "throw exceptions" flag. The copy always had exceptions enabled. o The resetdb example would print a bogus message about logging in as '1'@'1' instead of showing the actual values passed on the command line. This did not affect how it actually logged in. o Previous release tarball was missing a few text files present in the source repository. o Updated build paths for VC++ and MinGW to track a file layout change in Connector/C 6.1.2. 3.2.0, 2013.06.20 (r2747) o References to MySQL 5.1 have been replaced with 5.6, that being the current GA release. o All Windows builds now assume you're using Connector/C 6.1 instead of having installed the MySQL server on your machine just to get development files. If you are running a MySQL server on your development machine and don't want to install Connector/C just to make MySQL++ happy, see the README-*.txt file for your platform to get instructions on fixing the paths so the build system finds the development files under the MySQL server directory. o The generated VC++ 2008 project files now assume you want 64-bit executables. (It is 2013 now, after all.) Since the VC++ 2005 project files continue to be configured for 32-bit builds, the easiest way to get a 32-bit project in VC++ 2008+ is to import the VC++ *2005* project files, rather than adjust the build target settings of all 44 vc2008/*.vcproj files within the IDE. See README-Visual-C++.txt for more on this change. o Added Query::replacefrom(): like insertfrom() but it uses REPLACE statements instead of INSERT. Patch by Adrian Cornish. o Added support for SQL "unsigned float" columns. Patch by Leonardo Lang. o Added "abicheck" top-level build target, which runs the ISPRAS ABI checker tool (http://goo.gl/e19lD) against a predecided "ABI-stable" version of MySQL++, comparing it against the current version. This should help avoid future unplanned ABI breakages, as happened between 3.0.9 and 3.1.0. We have chosen not to revert those changes that broke the ABI, but instead have chosen to accept the 3.1.0 ABI as the new stable ABI for the rest of the 3.x series. Running the ABI checker is now part of the release process, so we should not change the ABI again until 4.0! o The Query::insert() and replace() overloads that take a pair of iterators now work with containers that only provide forward iterators. Idea by Adrian Cornish. o Using libtool again on Autotools systems. It gives us relocatable libraries, which is needed in some linking situations. Patch by Adrian Cornish. o VC++ release builds now have optimization enabled. This might also affect other toolchains that create separate Debug and Release builds, if Bakefile obeys the directive for those systems. (Such as, perhaps, Xcode.) Initial patch by Matthew Bradbury. o Fixed a crash in CommandLine mechanism when the usage message is called up for programs that have no "extra" parameter and corresponding usage appendage. Initial patch by "Crazy Pete". o Query::storein() now tolerates empty result sets, due either to DBMS failure or passing a query that never returns results, such as INSERT. o Exposed DBDriver::result_empty() as Query::result_empty(). We did this primarily because it was needed as a helper for the previous fix, but it could also be useful more broadly. o Added -Wextra to the pedantic build flags. o Fixed the "escape" manipulator so it will work with Null<> wrapped types. Patch by "Kemet". o ssqls2parse now depends on libmysqlpp. (It wasn't getting relinked when you changed the library.) o The configure script's test for the existence of mysql_ssl_set() got broken by a change in the mysql_loc.m4 test, causing it to always return "no" even if the platform's MySQL C API library did have the function. Therefore, the SslOption could never be set. Fixes this bug: stackoverflow.com/questions/7794408 o Fixed a missing a "buried headers" ifdef wrapper for type_info.cpp. Patch provided by Xavier Richez. o We now export the DBDriver class from the MySQL++ DLL when building on Windows. Client programs can now access it directly, instead of being able to access only the fields and members exposed through Connection and Query. Fix suggested by Xavier Richez. o MinGW builds no longer require that you manually create an import library for the MySQL C API DLL from a .def file we provide, which would inevitably get outdated. We can now link directly to the DLL, and rely on the MinGW linker to figure out the imports. o Split the -l flags out of LDFLAGS in the userman's example Makefiles. They're now in LDLIBS, which causes them to be put after -o $(EXE) by the default GNU make rules, where they should be. o Assorted documentation and build system improvements. o Assorted fixes for newer GCCs. 3.1.0, 2010.06.03 (r2670) o Default MySQL version now 5.1, having entered GA since 3.0.9. o Lots of platform updates tracked, lots of warnings from newer compilers squished. Most by me, some by Adrian Cornish. o Added Query::insertfrom(), plus associated classes SQLStream, NoTransactions, and the InsertPolicy hierarchy. Also adds examples/ssqls6.cpp, which shows how to use this new feature. Thanks for this feature go to Rick Gutleber, except for RowCountInsertPolicy, by me. o Added comparison operators to tiny_int<T>. Thanks for this patch go to Edward Diener. o Added SQLTypeAdapter::is_null(). This lets you retrieve a nullable column from the DB, then re-insert a value from that column back into the DB via a template query without explicit checks for null-ness; it will do the right thing now. o Added -f flags to lib/*.pl header file generating scripts to allow overriding the default limit of 25 fields for tqueries and SSQLSes without having to edit the file, as in previous versions of MySQL++. Also added --with-field-limit option to the configure script so you can give both -f options at once during the build process. This latter is especially useful for automated binary package builders. o The file lib/querydef.h (generated by lib/querydef.pl) now defines the MYSQLPP_TQUERY_MAX_PARAMETERS macro, giving the maximum number of parameters the functions in the generated file allow for template queries. Similarly, lib/ssqls.h (generated by lib/ssqls.pl) defines MYSQLPP_SSQLS_MAX_MEMBERS. o Added ConnectionPool::safe_grab(), which pings the grabbed connection before returning it. If the ping fails, we remove the dead connection from the pool and try again. This doesn't eliminate the possibility of returning a dead connection; there is no protection against race conditions. It is merely a best-effort attempt. o Added ConnectionPool::remove(Connection*), which removes a connection from the pool. o Added ConnectionPool::exchange(), which wraps remove() and grab(). It works like a customer support counter in a store: "I'm sorry, but this Connection is defective. Can I have another, please?" o Added a feature to Transaction, where it can send a SET TRANSACTION ISOLATION LEVEL query before it starts the transaction proper, affecting the isolation level and the scope of that change. o Added ScopedConnection class. Initial version by Joel Fielder, lots of changes by me. Using it instead of explicit safe_grab() and release() calls on the pool in examples/cpool.cpp. o Added FieldNames::operator[](size_type) overloads. This is necessary to correctly overload the base class versions inherited from std::vector. o FieldNames wasn't doing field-by-name matches case insentitively, most likely since 3.0.0 when we changed it to derive from std::vector. This caused SSQLS (at least) to be case sensitive. Fixed this and renamed the stock.sdate field in the SSQLS examples to stock.sDate to test this. o Added Query::replace(iter, iter), on the model of existing insert(iter, iter). Thanks for this patch go to David Walthour. o Added Query::operator!(), overriding basic_ios version so that "if (!query)" does the right thing. Fixes problem report in thread http://lists.mysql.com/plusplus/8594 o Query copy ctor and assignment operator now perform deeper copies, so you can pass Query objects around in certain ways that used to cause crashes. Thanks for this patch go to Steven Van Ingelgem. o Defined *_null variants for every sql_* typedef, wrapping all those earlier types in Null<>. All example programs now use these types instead of explicit Null<>-wrapped types. o Created a C++ command line parsing mechanism for the examples today, and for programs coming in the future. It uses the platform version of getopt() if available, substituting a public-domain implementation that gets built into MySQL++ itself otherwise. It's documented in the refman -- see the CommandLineBase class -- but it's in the newly created mysqlpp::internal namespace, which means we don't promise any sort of ABI or API stability for it. You're welcome to use it in your own programs, but expect it to change without warning. o Added a few missing MYSQLPP_EXPORTs to operator<<()s for stream manipulators, to allow their use when MySQL++ is built as a DLL. o Added backticks around table and column identifiers in all code paths exercised by dtest. There are some others remaining, particularly things like Row::field_list(). Thanks for this patch go to Adrian Cornish. o Added mysqlpp::NOW() which returns a value that, when inserted into a SQL query, results in a call to SQL's NOW() function. DateTime::now() -- added in 3.0.0 -- does the same thing, but this is shorter and matches the SQL syntax. o Calling DBDriver::disconnect() twice no longer calls mysql_close() twice. o Worked around a weakness on Windows that caused problems in code with a connect(), disconnect(), connect() call pattern, when also using a named pipe to connect to the DB. (There never has been a problem with this on other platforms or with other IPC mechanisms.) o Initializing a SQLTypeAdapter with a floating-point value equal to infinity or NaN results in SQL null if the type is also nullable, or 0 otherwise. Previously, we got an implementation-defined string, which could give invalid SQL, or could give 0, a different value from NaN, infinity, or SQL null. This does collapse the notions of NaN and infinity, but the MySQL reference manual doesn't say how you're supposed to preserve these differences. o Removed the dependency of stadapter.h on sql_types.h, just to get sql_tinyint*. #including tinyint.h instead, and using equivalent types to what sql_types.h defines. This is necessary because sql_types.h should be one of the last things included from mysql++.h, so that it can define sql_* equivalents for everything else in MySQL++, which means all those other things need to be #included by that point. o The "find MySQL++" autoconf macro (config/mysql++.m4) now searches for the library in lib64 subdirectories everywhere it also looks in lib. We did this for the C API finder macro way back in MySQL++ 2.2.0, and only neglected to do it for this macro because it's not used by MySQL++ itself, just provided as a courtesy to MySQL++ users that also use autoconf. o Also improved the "find C API" macro (config/mysql_loc.m4) so it, too, is more useful in third-party projects. o Moved private FieldNames::str_to_lwr() method out into its own module, in the new mysqlpp::internal namespace, so other modules can use it. Also added an overload for this new global method taking std::string instead of char*. o userman build process can now find FOP when installed from the standard Ubuntu/Debian package repository. o No longer generating refman.pdf. It's difficult to generate properly on some platforms, and isn't all that useful anyway compared to the HTML version, which builds properly everywhere. o Dropped custom.h backwards-compatibility header. (Deprecated over a year ago in MySQL++ 3.0.0.) o Fixed a bad pointer access crash in Connection::set_option() triggered when the option set call fails. Thanks for this patch go to Kevin Regan. o ReconnectOption behavior now knows about a fix in MySQL 5.1.6 and newer that lets you set it either before the connection is up, or after. If you try to set this option when MySQL++ is built against earlier versions of the MySQL C API, it will refuse to set the option because it knows the option will be reset when the connection comes up. o No longer trying to make the C API library read from a "my" options file before connect. It does that by default, and the file is supposed to be .my.cnf anyway. o Reworked the load_jpeg example code for clarity, extracting load_jpeg_file() routine as an implementation detail and making that use the C++ stringstream "slurp into string" idiom instead of allocating a C char buffer and copying that into a std::string. o Restored support for repeating query parameters. Apparently you could say things like "stuff %0 morestuff %0" in v2.1, but this was broken by initial 1-parameter fixes in v2.2. This patch reportedly lets us have both things at once, and improves handling of 1-parameter template queries in general. Thanks for this patch go to Martin Gallwey. o Added examples/tquery4.cpp based on test code and feedback from Martin. o Put Comparable class in namespace mysqlpp, where it should always have been. Aside from being just plain wrong, it caused a conflict with Boost if you used its Comparable class and hoist them both into the global namespace. Thanks for this patch go to Michael Radzewitz. o Fixed all the known problems with the Xcode project files. o Skeletal support for SSQLS v2. Doesn't do anything useful yet, it just got caught up in the need to release 3.1 as-is. o Various enhancements to the test suite. o Many, many documentation enhancements. 3.0.9, 2009.02.04 (r2442) o It is now possible to use Null<T> objects in const context. o Query was emitting thousands separators when used in some locales. Thanks for the fix go to Tomaž Šolc. o Restored support for using Query::storein() with template queries. Was mistakenly removed in the 3.0.0 development process. o GCC 4.4 build fixes. Thanks for this go to Remi Collet. 3.0.8, 2008.11.27 (r2432) The "Thanksgiving" release o Fixed a VC++ build error introduced in 3.0.7 in the Sun CC fix. o Fixed the Makefile we generate from Makefile.simple for the devel RPM. The recent Bakefile upgrade changed the output so our munger stopped munging. o Changed all instances of "CREDITS" in header comments to "CREDITS.txt". o Brought ebuild file up to date with what Gentoo has been using for 2.3.2. 3.0.7, 2008.11.21 (r2423) o Fixed bug where initting a Query with a query string and then appending more to it with operator <<() would start overwriting the beginning of the buffer. Thanks for the fix go to Chris Frey. o Added String::empty(), to parallel std::string better. o Added SQLTypeAdapter ctor for Null<String>, to allow SSQLS with NULL BLOB columns. Thanks for this patch go to Russell Robinson. o Passing on "throw exceptions" flag in Query::storein() to the temporary Row objects it creates. (Should have done this all along.) o All MySQL++ classes with operator[]() and at() methods now throw the new BadIndex exception on out of range indices now, unconditionally. Before, it was a mishmash of MySQL++-specific mechanisms, std::range_error, and unchecked access. o Fixed some bugs in load_jpeg and cgi_jpeg examples that prevented them from working correctly on Windows. o Squished some warnings and incompatibilities that caused difficulty with Solaris CC. o Several minor fixes to allow building on Cygwin again. o Dedicated VC++ 2008 support. (Not just a clone of VC++ 2005 project files in a different directory.) o Lots of documentation improvements. 3.0.6, 2008.08.16 (r2350) o Several fixes to allow thread-aware build on Solaris o More improvements to search for Fink version of C API library. o Various improvements to Windows installer (install.hta) 3.0.5, 2008.08.06 (r2332) o Replaced install.bat with new install.hta, which has a GUI and a lot of embeded logic for doing The Right Thing, which we couldn't do in a dumb batch file. o Several fixes to allow it to build on Solaris 10. o Fixed a bug in comparison of Null<T> to T: wouldn't always give the right result for one particular combination of argument values and order of parameters to operator <(). It wouldn't fail all the time, either; it depended on the way the system's memory allocator dealt with newly allocated RAM. The bug was discovered during the Solaris 10 porting effort, but it is not a Solaris-specific bug. o Split Linux-specific material out of README-Unix.txt into README-Linux.txt, and created README-Solaris.txt. o Shipping a vc2008 directory. Populated by bootstrap script with copies of vc2005 files when those are newer, with the idea being to update them by hand by running them through VC++2008 before release. o Several fixes to VS-only examples. They hadn't been updated to track several of the changes in MySQL++ v3, so they wouldn't build OOTB at all, crashed when you did get them building, and emitted a lot of warnings during the build. Cleaned it all up. o Autoconf now explicitly checks whether we need to link to zlib to link to MySQL C API library. It used to be required, but lately, MySQL has been shipping the library with zlib stuff embedded, causing multiply defined symbol errors on some systems. o configure script now looks in more locations for the MySQL C API library, adding default locations for Fink and Solaris. 3.0.4, 2008.07.02 (r2303) o Fixed a few bugs in SslOption that prevented it from actually working. If you've been having SSL problems since upgrading to MySQL++ v3, this is why! Thanks for these patches go to Petteri Kiiskinen. o Changed type of String's internal "size" typedefs so it'll build without errors on 64-bit systems where these ints are different sizes. o Many user manual improvements. 3.0.3, 2008.05.11 (r2284) o Fixed query well-formedness handling in Query::store() and use(). It was quietly eating these errors, confusing them with the no-results case. o Fixed examples/cpool.cpp to build without thread support. o No longer hiding all stdint.h typedefs inside namespace mysqlpp. o Fixed mysqlpp::String comparisons of empty strings against nonempty strings; if the empty string was on the left hand side, it would succeed because it was only comparing against characters in the empty side, which matches everything. (Fixes bug 11588.) 3.0.2, 2008.04.13 (r2275) o Increased float to string conversion precision from 7 to 9 and double from 16 to 17 digits. Previous values weren't enough near the maximum values that each can hold. o Replaced Query's safe bool mechanism with an override of basic_ios::operator void*() to avoid a conflict between the two mechanisms. As the base class version isn't virtual, this is arguably evil, but it should be harmless in typical use. Besides, testing Query in bool context usually isn't the right thing anyway: test the result set instead. o Made ConnectionPool::grab() virtual. o Overriding ConnectionPool::grab() and release() in examples/cpool.cpp to show how to do connection-in-use count limiting. Also, added a few more output indicator states to allow one to better understand program flow. 3.0.1, 2008.03.23 (r2263) o String objects can now be compared to mysqlpp::null directly. o Added a template operator== and operator!= to String, syntactic sugar for the existing String::compare() methods. o String::compare() now returns 0 ("equal") when one of the strings is an uninitialized String() (no refcounted buffer) and the other is empty. It used to consider any initialized string greater than an uninitted one. An uninitialized String appears empty, though, so this was incorrect. o Made Connection::thread_aware(), thread_start() and thread_end() static methods, so they can be called before you create your first connection. Ditto for DBDriver versions of these methods. o Calling Connection::thread_start() and thread_end() in examples/cpool.cpp, as appropriate. Above changes were necessary to make this work sensibly. o Made ConnectionPool::release() virtual, so your pool subclass can override it. o Added ConnectionPool::size(), so a subclass can know the current number of extant connections. o No longer single-quoting NOW() call generated for default init of DateTime type when building queries from SSQLS objects in Query::insert(), replace() and update(). The template query and stream interfaces of Query treated NOW() correctly already. o Fixed a bug that left SSQLS::table_override_ uninitted if you used certain of the generated ctors or set() member functions instead of others used by the examples. This could cause a crash any time you caused SSQLS.table() to be called, such as when passing the SSQLS to Query::insert(). o Minor memset bug fixed in test/uds.cpp. Patch by Dave Jones. 3.0.0, 2008.02.29 (r2236) The "Giant Leap Forward" release THIS IS NOT A DROP-IN REPLACEMENT FOR MySQL++ v2.x! You will have to recompile your program against this version of the library, and you will almost certainly have to make code changes as well. Please see these sections in the user manual for information on migrating your code to this new version: http://tangentsoft.net/mysql++/doc/html/userman/breakages.html#api-3.0.0 http://tangentsoft.net/mysql++/doc/html/userman/breakages.html#abi-3.0.0 o Added ConnectionPool class, primarily to let multithreaded programs share a set of Connection objects safely in situations where it isn't acceptable to have a Connection per thread. o Created examples/cpool.cpp to demonstrate this new class. o Added RefCountedPointer template, which provides automatic memory management and data sharing. It's not intended for use outside of MySQL++ itself, but it's the mechanism behind everything below where reference counting is mentioned. I created the initial version of it, but Jonathan Wakely almost completely rebuilt it, and Joseph Artsimovich provided helpful commentary and advice as well. o Many improvements to Specialized SQL Structures (SSQLS): - Renamed custom* to ssqls*. There's still a custom.h which #includes ssqls.h for you, but it's only intended to ease the transition to the new name. It will go away in a future release, probably as soon as v3.1. - SSQLSes are finally compatible with Null<>-wrapped types. This feature is based loosely on the "Waba" patch posted to the mailing list back in the v2.0 days, but extended to allow Null<T> types for key fields. (The Waba patch only allowed these types in non-key fields.) - It's no longer necessary to define a different SSQLS for each different field set you use in queries. That is to say, you can define an SSQLS for an entire table and store just a subset of the table in it now, with the other fields keeping default values. Removed examples/custom6.cpp, as custom1.cpp can now demonstrate the same thing, implicitly. - An SSQLS's field order no longer has to match the order of fields in the result set it is populated from. - As a result of previous, removed sql_create_c_order_* macros; they have no purpose now. - Removed order parameters from sql_create_complete_*, which now gives it the same functionality as sql_create_c_names_* so removed the latter, too. - Removed "basic" variants of SSQLS creation macros. They've been unofficially deprecated by dint of being all but undocumented and unexemplified for a very long time now. - It's now possible to use mysqlpp::String, Date, DateTime, and Time types in the key field positions in an SSQLS as they now support the necessary comparison interfaces. - If you use a floating-point data type in one of the key field positions, it no longer uses exact comparison logic. Instead, it now does [in]equality comparisons by testing whether the difference between two floating-point values is less than a configurable threshold defaulting to 0.00001. - You can now use 'bool' type in an SSQLS. - Renamed _table static member variable in each SSQLS to table_ and made it private. There are now public setter and getter methods, table(). - Added per-instance table name overriding via instance_table() setter. table() getter returns static version if this is not set, so it's still a global setting by default. o You can now use mysqlpp::null as a template query parameter to get a SQL null. o Replaced template ColData_Tmpl<T>: - Used to have typedef ColData_Tmpl<std::string> MutableColData. It was used only once within MySQL++ itself, and was never documented as a class for end users. This one use within the library was a crock, so we just replaced this use with std::string and removed the typedef. - This left just one use of ColData_Tmpl<T>, instantiating it with the MySQL++ utility class const_string, basically a clone of std::string with all the mutating features removed. Folded the functionality of const_string into the template, renamed the result to String, and deleted the const_string class. It'd be a complete std::string replacement -- with SQL-related enhancements -- if it were modifiable, but MySQL++ doesn't need it to be modifiable. Yet, it's still the closest thing MySQL++ has to its own string type; thus the name. - Replaced its internal buffer management with a much more clever reference counted scheme. This shows its greatest advantage in the return from Row::operator[](), which for technical reasons must return by value, not by reference as is more common. This lets you pass around Strings by value while having the efficiency of reference semantics. This can be important with large return values, like BLOBs. - Converting String to numeric types (ints, floats...) uses a new, cleaner system by Jonathan Wakely. Unless you were abusing weaknesses in the old system, you won't see a difference. It's just more robust and flexible. o Redesigned SQLString: - It used to derive from std::string, and while MySQL++'s internals did use it in place of std::string, these places didn't take advantage of the additional features offered by SQLString. So, replaced all those uses with std::string. - All the remaining uses are MySQL++ public interfaces that need to be able to accept any of many different data types, and we want that data to be automatically converted to a SQL-compatible string form. Because it no longer has the parentage to be a general-purpose string type and MySQL++ has a new contender for that role (String), renamed SQLString to SQLTypeAdapter to reflect its new, limited purpose. ("STA" for short.) - Since we don't have the std::string base class to manage the string buffer any more, using the same reference counted buffer mechanism as String. In addition to saving code by not creating yet another buffer management mechanism, it means objects of the two classes can share a buffer when you assign one to the other or pass one to the other's copy ctor. - Added many more conversion ctors. - STA interfaces using the 'char' data type now treat them as single-character strings instead of one-byte integers, as does the Standard C++ Library. - Added mysqlpp::tiny_int interfaces to STA to replace the former char interfaces for those needing one-byte integers. o As a result of the ColData -> String redesign, removed Row::raw_*(). Before String copies were efficient, this was helpful in accessing BLOB data efficiently. It was also required back when ColData didn't deal correctly with embedded null characters, but that reason is gone now, too. o Row::operator[](const char*) no longer unconditionally throws the BadFieldName exception when you ask for a field that doesn't exist. It will still throw it if exceptions are enabled, but if not, it'll just return an empty String. This was necessary to make the SSQLS subset and field order independence features work. o Similarly, Result::field_num() returns -1 when exceptions are disabled and you ask for a field that doesn't exist. o You can now use the OptionalExceptions mechanism to disable exceptions on const MySQL++ objects. o Redesigned query result classes: - Instead of Result deriving from ResUse, the two derive from a common base class -- ResultBase -- containing the bits that are truly the same between them. Before, Result inherited several methods that didn't really make sense for "store" query result sets. - Renamed Result to StoreQueryResult and ResUse to UseQueryResult so it's clearer what each is for. - Renamed ResNSel to SimpleResult. - Made all SimpleResult data members private and hid them behind const accessor functions of the same name. - The result set classes all used to be friends of Connection for various lame reasons. Since they are created by Query, and Query has a good reason for a strong relationship with Connection, moved Connection access out of each result set class into the code in Query that creates that type of result set object. - StoreQueryResult now derives from vector<Row> in addition to ResultBase; it used to merely emulate a vector of Rows, poorly. It can now dispose of the MYSQL_RESULT at the end of object construction, because it creates all the Row objects up front instead of on the fly. And as a result of *that*, operator[] returns by reference instead of by value, operator -> works correctly on iterators, all STL algorithms work, etc., etc. - IMPORTANT COMPATIBILITY BREAK: because we used fetch_row() stuff in Result previously, it was okay to index past the end of the result set: you'd just get a falsy Row when you did this, just as happens when doing the same thing in a "use" query. The simple1 and simple2 examples did this, so it's likely that code exists that takes advantage of this misfeature. New versions of these examples show how to index through a StoreQueryResult without running past its end. - ResUse used to delay creation of its FieldNames and FieldTypes objects until the point of need. This had several implications for thread and exception safety that we fix by just creating them in the ctor. If your code is multi-threaded and was avoiding certain usage patterns due to crashes, it's worth trying your preferred way again. - Result sets create a few data structures to hold information common to all rows in that set. The row objects need access to these shared data structures, so on creation each gets a pointer back to the result set object that creates it. This was efficient, but required that a result set object outlive any row objects it creates. Now these shared data structures are reference-counted, decoupling the lifetime of the child row objects from their result set parent. - Copy operations for result sets used to actually be "moves" before, for efficiency. (MySQL++ itelf only copied result sets in returning them by value from the query execution methods of Query, so this was acceptable if you didn't do anything uncommon with these objects.) Reference counted data structures allow us to have copy semantics now without sacrificing efficiency. - You can now use Query::storein() with an STL container of Row objects now, instead of having to use SSQLSes. The lifetime issue guaranteed a crash if you tried this before. - Removed a bunch of unnecessary alias methods: - columns() -> num_fields() - names() -> field_names() - rows() -> num_rows() - types() -> field_types() - Renamed several methods for grammar reasons: - fields(unsigned int) -> field(unsigned int) - names(const std::string&) -> field_num(const std::string&) - names(int) -> field_name(int) - types(int) -> field_type(int) - Removed several "smelly" methods: - purge() - raw_result() - reset_names() - reset_field_names() - reset_types() - reset_field_types() o Field class used to just be a typedef for the corresponding C API class. Now it's a real C++ class providing a more MySQL++ sort of interface, plus good OO things like information hiding and implementation detail abstraction. This changes several things about the interface. o Fields class was basically a specialized std::vector work-alike for dealing with the C API to get access to MYSQL_FIELD objects and present them as contained Field objects. New Field type let us replace it with "typedef std::vector<Field> Fields" o Major improvements to the quoting and escaping mechanisms: - Replaced almost all of the type-specific interfaces in manip.h with a single version taking STA. The compiler can convert almost anything to STA without losing any information we need for correct quoting and escaping. This has the side benefit that we can now do correct quoting and escaping for more data types now, including plain C and C++ string types. - Fixed a bug in quote_double_only manipulator for String: was using single quotes by mistake. - Escaping and quoting only works in instances where MySQL++ can tell you're building a SQL query and are using a data type that requires it. This affects many things, but the one most likely to cause trouble is that inserting MySQL++'s quoting and escaping manipulators in non-Query ostreams is now a no-op. - Added escape_string() member functions to Query and SQLQueryParms::escape_string(), and removed the global function of the same name. Because these are tied indirectly to a Connection object, this also has the effect that escaping is now aware of the current default character set used by the database server. There's only one case where this isn't done now, and that's when we're disconnected from the server. - Previous two items form a trade-off: if your code was depending on MySQL++ to get SQL escaping and it no longer happens for what we consider a good reason, you can build a replacement mechanism using these new functions. Quoting needs no special support in MySQL++. - Removed 'r' and 'R' template query parameter modifiers, which meant "always quote" and "always quote and escape" regardless of the data type of the parameter. There are no corresponding manipulators (for good reason), so the removal restores symmetry. o Created DBDriver class from code previously in Connection and Query to almost completely wrap the low-level MySQL C API: - Connection creates a DBDriver object upon connection and passes a pointer to it down to Query objects it creates. In turn, they pass the pointer on to any of their children that need access to the C API. - Nothing outside DBDriver calls the C API directly now, though DBDriver leaks C API data structures quite a lot, so this feature doesn't constitute "database independence." See the Wishlist for what must be done to get to that point. o Completely redesigned the connection option setting mechanism: - There's now just a single Connection::set_option() method that takes a pointer to the abstract Option base class, and there is an Option subclass for every connection option we understand. Thus, type errors are now caught at compile time instead of at run time. - Replaced Connection::enable_ssl() with SslOption class. - Enabling data compression and setting the connection timeout are no longer set via parameters to Connection interfaces. These are now set with CompressOption and ConnectTimeoutOption. - Similarly, removed client_flag parameters from Connection's ctor and connect() method and added corresponding Option subclasses. There's about a dozen, so rather than list them here, look for similarly-named classes in lib/options.h. o Added Connection::count_rows() to execute "SELECT COUNT(*) FROM tablename" queries for you. o Moved Connection::affected_rows(), info() and insert_id() methods to class Query, as they relate to the most recently-executed query, not to the connection. o Several method name changes in Connection: - client_info() -> client_version() - host_info() -> ipc_info() - proto_info() -> protocol_version() - server_info() -> server_version() - stat() -> status() o Removed Connection::api_version(). It does the same thing as client_version(). o Lots of changes to Date, DateTime, and Time classes: - If you use the default constructor for DateTime and don't subsequently set its year, month, day, hour, minute or second data members to nonzero values, it becomes the SQL function "NOW()" in a query string. You can also use DateTime::now() as syntactic sugar for this. - As a result of above, had to hide all of DateTime's data members behind accessor functions, to keep the state of the object consistent. (If it's initialized as "now" and you give it an explicit year value, say, it is no longer "now", so the setter has to clear the now-flag.) There are getters and setters for year, month, day, hour, minute and second, all named after the member. - Did the same for Date and Time for consistency, even though it isn't technically required. - The sql_timestamp typedef now aliases DateTime instead of Time. - Renamed template class DTbase<T> to Comparable<T>. The fact that it's the common base class of all date and time classes is irrelevant; making subclasses comparable is what it does, so that's what it should be named after. - Added a DateTime ctor taking discrete year, month, day, hour, minute, and second values. - Implicit conversion from stringish types to the date and time types is no longer allowed. This is part of the "Waba" Null<T> patch mentioned above; allowing implicit conversions would break this new feature. - Added operator std::string and str() methods to all of these classes. Adding this to the existing operator << support, you now have several ways to convert these objects to string form. - Added time_t conversion to Date and Time classes. DateTime already had it, since it's more legitimate to convert time_t to DateTime, but you could already "slice" it with something like Time(DateTime(time(0))) so there's no point pretending you can't get from time_t to Date or Time. Might as well legitimize it. o Improved tiny_int class: - Turned it into a template parameterized on the value type so you can get both signed and unsigned TINYINTs - Changed the sql_tinyint and sql_tinyint_unsigned typedefs to use mysqlpp::tiny_int<VT> instead of raw chars - Added a bool conversion ctor and operator, and typedef'd it to sql_bool and sql_boolean to match MySQL server behavior o Added many more sql_* typedefs. We now have a typedef for every type the MySQL server knows about, including those it supports just for compatibility with other database servers. o Changed the sql_*int* typedefs to use integer types of the same size as the MySQL server. (Run test/inttypes.cpp to test it.) o Added copy ctor and assignment operator to Row. o Row::operator[]() takes int now instead of unsigned int. This finally (!) makes it possible to say row[0] without the compiler giving an ambiguous overload error. o Changed all uses of row.at(0) in the examples to row[0] o Added operator[] to all classes that only had at(). o Query now automatically resets itself unless the query fails or you're using template queries. In either case, the contents of the query's internal buffers are considered precious, either for debugging, or future queries. Except when using template queries, this means you may be able to avoid calling Query::reset() entirely. It's still safe to call reset() as before, just unnecessary most of the time. o Removed reset_query parameter from all Query methods. It was almost completely broken before, and above change does what was really wanted to begin with. o Query::store_next() and Result::fetch_row() no longer throw the EndOfResults and EndOfResultSets exceptions; these are not exceptional conditions! These methods simply return false now. o Removed examples/usequery.cpp: there's no essential difference between what it did and what examples/simple3.cpp does now as a result of the previous change. o Added Query::exec(void), paralleling Query::execute(void). o Removed Query::preview(). The most direct replacement is str(), which has always done the same thing. o You can now insert a Query object into an ostream to get a copy of the built query. This means Query::str() is only necessary when using template queries. o Removed overloads of Query::execute(), store(), and use() that take const char*. It was redundant because const char* converts implicitly to STA, for which overloads already exist. o Renamed Query::def to Query::template_defaults to make its purpose clearer. o Query::error() now returns const char*, not a std::string by value. There's no point in making a copy of the error string. The method is now const as well, as it doesn't change the Query object. o Added Query::errnum(), which just wraps Connection::errnum(). o Added error number parameters and accessor functions to BadQuery, ConnectionFailed and DBSelectionFailed exceptions, to preserve the state of Connection::errnum() at the point of the exception, so you don't have to rely on this value remaining unchanged during the exception throw process. All places that use these exceptions now include this value where possible. Thanks for the initial patch go to Jim Wallace. o Removed Lockable mechanism from Connection and Query; it was conceptually flawed. See the new user manual chapter on threading for advice on using MySQL++ safely without locking. There is mutex locking now in ConnectionPool, but that's it. o Connection::query() now takes an optional query string, allowing the returned Query object to start off with a value. Especially useful when the query string is static, either because it's a simple query or because it's a template. You can now build chains like "if (conn.query("CREATE INDEX ...").exec()) { ..." o Added Connection::thread_aware(), thread_end(), thread_id() and thread_safe(). See user manual's threading chapter for explanations. o Renamed "success" data members in Connection, Query and SimpleResult (neé ResNSel) to "copacetic_", making them private if they weren't before. This better reflects their actual use, which isn't to say that there has necessarily been actual success, but rather that everything's okay with the object. o Removed success() member functions from above classes. All can be tested in bool context to get the same information. o Replaced all operator bool()s in MySQL++ classes with safer alternatives. See http://www.artima.com/cppsource/safebool.html Thanks to Jonathan Wakely for much helpful commentary, advice, and code used in these mechanisms. o Decoupled Connection::copacetic_ from Connection::is_connected_. It is now possible for the object to be copacetic without being connected. However, if it tries to connect and fails, then it is not copacetic. If it is copacetic and not connected, it means we haven't even tried to connect yet, a useful distinction. o Collapsed Connection's host, port, and socket_name down into a new combined 'server' parameter which is parsed to determine what kind of connection you mean. These interfaces are still compatible with v2.3 and earlier up through the port parameter. There are differences beyond this. o Added TCPConnection, UnixDomainSocketConnection and WindowsNamedPipeConnection subclasses for Connection giving simpler construction and connect() method interfaces for instances where you know what kind of connection you want at compile time. o Changed Connection::ping() return value from int to bool. o Renamed NullisNull to NullIsNull -- capital I -- and similar for NullisZero and NullisBlank. o It's now a compile-time error to try to convert a MySQL++ representation of a SQL null to any other data type, rather than a run-time error as in previous versions. Removed BadNullConversion exception as a result. o Way back in v1.7.x we used the BadQuery exception for all kinds of exceptional conditions, not just bad queries. Replaced most of these in v2.0.0 with new dedicated exceptions, but a few remained: - Errors that occur during the processing of a "use" query after the query itself executes correctly now throw UseQueryError. It's not a "bad query", because the query executed successfully. It just choked during subsequent processing, so it's a different exception. Thanks for this patch go to Jim Wallace. - Replaced BadQuery exceptions thrown in Row constructor due to bad ctor parameters with new ObjectNotInitialized exception This is also Jim Wallace's work. o The examples now all use getopt() type command line options instead of positional options. This makes it possible to pass options in any order, leave at their default options that used to be in the middle of the sequence, and offer different subsets of options for different programs. Also allows for special internal-use options, like -D passed by dtest to let examples change their behavior when run under dtest to produce only predictable output. o Split old libutil functionality into two modules, one holding all the "print data" functions, and another holding all the command line parsing stuff. This makes it easier for newbies to ignore the command line stuff, treating it like a black box. The wish to understand the "print data" routines is much more common, so the two needed to be disentangled. o Renamed examples' libutil to libexcommon. o Removed connect_to_db() libutil function. It combined command line parsing, which users don't care about, with database connection establishment, which they do care about. Now the examples just call out to libexcommon to parse the command line, and use the values they get back to explicitly make the connection, so it isn't hidden. o Removed cchar and uint typedefs. o Redesigned dbinfo example's output to be easier to read. o Fixed an output formatting bug created in 2.3.0 that caused the tabular output from examples to not line up. o Renamed examples/tquery.cpp to tquery1.cpp. Created tquery2.cpp to demonstrate passing parameters via a SQLQueryParametrs object instead of discretely. Created tquery3.cpp for testing unquoted template parameters, such as integers. o Renamed fieldinf1.cpp example to fieldinf.cpp, and simplified its output so it can be part of the dtest sequence. o Renamed examples/xaction.cpp to transaction.cpp. It created too much cognotive dissonance whenever thinking about both it and lib/transaction.cpp. o Added examples/deadlock.cpp, to test handling of exceptions due to server-side transaction deadlock detection. Also added code to resetdb to create a table needed to test this. Initial version created by Jim Wallace to test the value of all his BadQuery exception work, with reworking by me. o Greatly expanded dtest suite. Primary change is that we now have a handful of unit tests, where in v2.3.2 we only tested a subset of the examples. Still very low coverage ratio, but it's a big improvement. o Optimized #includes, especially in lib/*.h to reduce dependencies and thus compile time when one of these changes. o Fixed a typo in RPM filename generation that prevented -devel RPM from recognizing that the corresponding MySQL++ library RPM was installed. o RPM spec file improvements by Remi Collet. o Renamed NO_LONG_LONGS to MYSQLPP_NO_LONG_LONGS to avoid a risk of collision in the global macro namespace. o First cut at Xcode2 project support. Testing needed! o Debug build of library on VC++ and Xcode have a _d suffix now so you can have both versions of the library installed without conflict. o Moved the VC++ 2003 project files into a new vs2003 subdirectory because there are so many of them. Also created vs2005 subdirectory for VC++ 2005 and 2008 compatible project files. 2005 makes an even bigger mess of the directory containing the .sln file, so the incentive is bigger. Plus, we have to disable several things to get VC++ 2003 to build MySQL++ now, so we need a special 2005+ version of the project files for a complete build, if the user has one of the newer compilers. o ...plus dozens of small bug fixes and internal enhancements, many documentation improvements, and expansion of support for newer operating systems and compilers. 2.3.2, 2007.07.11 (r1669) 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. 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. 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. 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) o Fixed the new localtime() alternative selection code for VS2003 and various uses of STLport. 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. o Fixed a bug in the Connection copy ctor where it didn't completely initialize the object. 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) o MinGW and Cygwin will now build and link to mysqlpp DLLs. 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. 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/html/userman/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. o Fixed some compiler warnings in custom*.h. Thanks to Chris Frey for this patch. 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. 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. o PDF version of user manual now has hard page breaks between chapters. o Removed complic1 example. Wasn't pulling its own weight. Everything it is supposed to demonstrate is shown in other examples already. 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. 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. 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.) 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. o Every declaration in MySQL++ is now documented in the reference manual, or explicitly treated as "internal only". 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. o Improved a lot of existing reference manual documentation while adding the new stuff. 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. 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). 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. o Once again, the main include file was renamed, this time to mysql++.h. Hopefully this is the last renaming! o mysql++.hh still exists. It emits a compiler warning that the file is obsolete, then it #includes mysql++.h for you. 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. 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++. o There is now only one place where conditional inclusion of winsock.h happens: platform.h. o Beautified the example programs. 1.7.19, 2004.10.25 (r186) 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. 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.) 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. 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.) 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 / |
︙ | ︙ |
Deleted HACKERS.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added HACKERS.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | # Hacking on MySQL++ If you are going to make any changes to MySQL++, this file has some hints and commentary you may find helpful. ## Code Repository Access MySQL++ uses the [Fossil][fsl] [distributed version control system][dvcs]. See its [quick start guide][fslq] if you are unfamilar with Fossil. You must be running Fossil version 2.1 or higher to access the MySQL++ repository. If your operating system includes an older Fossil package, you will either have to install [an official binary][fslb] or [build it from source][fsls]. To clone the code repository anonymously, say: $ fossil clone https://tangentsoft.com/mysqlpp mysqlpp.fossil If you have a developer account on the MySQL++ Fossil instance, just add your username to the URL like so: $ fossil clone https://username@tanentsoft.com/mysqlpp mysqlpp.fossil That will get you a file called `mysqlpp.fossil` containing the [abridged version history][avh] of MySQL++ back to the project's founding. The repository clone file can be named anything you like. Even the `.fossil` extension is just a convention, not a requirement. To "open" the repo clone so you can hack on it, say: $ mkdir mysqlpp $ cd mysqlpp $ fossil open ../mysqlpp.fossil We created a new subdirectory because the `open` command checks out the tip of the repository's trunk into the current directory by default. As with `mysqlpp.fossil`, you can call the working directory anythihg you like. I actually prefer a working tree that looks like this: ~/museum/ # Where fossils are kept mysqlpp.fossil ~/src/ # Working tree for software projects mysqlpp/ skull/ # Fossil head, get it? I crack me up. trunk -> skull/ # Alias to match Fossil branch naming some-branch/ # Separately-opened working branch 3.2.3/ # Release branch checkout Fossil will let you make any modifications you like to your local repository copy. For those with privileges on the upstream copy, checkins get automatically synced with it by default. (If you prefer Git or Mercurial style two-phase commits, you can say `fossil settings autosync off`.) If you don't have such permissions, you just modify your local copy, then have to merge in upstream changes when updating your local clone. Developers are expected to make all changes that affect the libary's API, ABI, or behavior on a branch, rather than check such changes directly into the trunk. Once we have discussed the change on the [mailing list][ml] and resolved any isssues with the experimental branch, it will be merged into the trunk. Creating a branch in Fossil is scary-simple, to the point that those coming from other version control systems may ask, "Is that really all there is to it?" Yes, really, this is it: $ fossil checkin --branch new-branch-name That is to say, you make your changes as you normally would; then when you go to check them in, you give the `--branch` option to the `ci/checkin` command to put the changes on a new branch, rather than add them to the same branch the changes were made against. At some point, the trunk version becomes the next major version. Stable versions become either tags or branches. (The only difference between tags and branches in Fossil is that branches may have subsequent changes made to them.) [avh]: https://tangentsoft.com/mysqlpp/wiki?name=Abridged+Version+History [dvcs]: http://en.wikipedia.org/wiki/Distributed_revision_control [fsl]: http://fossil-scm.org/ [fslb]: http://fossil-scm.org/index.html/uv/download.html [fslq]: http://fossil-scm.org/index.html/doc/trunk/www/quickstart.wiki [fsls]: http://fossil-scm.org/index.html/doc/trunk/www/build.wiki [ml]: https://lists.mysql.com/plusplus/ ## Bootstrapping the Library When you check out MySQL++ from Fossil, there are a lot of things "missing" as compared to a distributed tarball, because the Fossil repository contains only source files, no generated files. The process that turns a fresh MySQL++ repository checkout into something you can build and hack on is called bootstrapping. Boostrapping is best done on a modern Unix type platform: Linux, OS X, BSD, Solaris...any version released since 2005 or so. It's possible to do it on Windows, but much harder; we cover the options below in a separate section. Two of the tools you need to do this are commonly available on Unixy systems, at least as an option: Perl 5, and GNU Autoconf 1.59 or higher. If they're not installed, you can probably run your system's package manager to install suitable versions. There's a third tool you'll need to bootstrap MySQL++, called Bakefile, which you can get from http://bakefile.org/ You will need Bakefile 0.2.5 or higher, which in turn requires Python 2.3 or higher to run. To build Bakefile from source, you will also need SWIG, so if you don't have that, you'll want to use one of the binary builds of Bakefile. Once you have all the tools in place, you can bootstrap MySQL++ with a Bourne shell script called bootstrap, which you get as part of the Fossil checkout. It's fairly powerful, with many options. For most cases, it suffices to just run it without any arguments: $ ./bootstrap For more unusual situations, here's the complete usage: $ ./bootstrap [no{doc,ex,lib,opt}] [pedantic] [bat] \ [configure flags] Arguments: * `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 no good for any other purpose. * `noex` The generated `Makefiles` and project files won't try to build any of the examples. * `nolib` The generated `Makefiles` and project files won't try to build the MySQL++ library. * `nomaint` Turn off "maintainer mode" stuff in the build. These are features used only by those building MySQL++ from Fossil. The `dist` build target uses this when creating the tarball. * `noopt` Compiler optimization will be turned off. (This currently has no effect on MinGW or Visual C++.) * `pedantic` Turns on all of GCC's warnings and portability checks. Good for checking changes before making a public release. * `bat` Asks `cmd.exe` to run `bootstrap.bat` for you. This is useful when using Cygwin just as a command shell in preference to `cmd.exe`, as opposed to using Cygwin to build MySQL++ using its native tools. Passing 'bat' stops all command line processing in the bootstrap script, so if you also pass some of the other options, make "`bat`" last. The only options that affect the built project files and `Makefiles` work are the no* ones. * `configure` script options 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.txt for more on configure script options. ## Bootstrapping the Library Using Only Windows The thing that makes bootstrapping on Windows difficult is that one of the required steps uses a Unix-centric tool, `autoconf`. This section is about working out a way to get that working on Windows, or avoiding the need for it, so you can get on with hacking on MySQL++ on Windows. The thing `autoconf` does that's relevant to Windows builds of MySQL++ is that it substitutes the current MySQL++ version number into several source files. This allows us to change the version number in just one place — `configure.ac` — and have it applied to all these other places. Until you do this step, an Fossil checkout of MySQL++ won't build, because these files with the version numbers in them won't be generated. ### Option 1: Copy the generated files over from a released version Only one of these generated files is absolutely critical to allowing MySQL++ to build: `lib/mysql++.h`. So, the simplest option you have to bootstrap MySQL++ entirely on Windows is to copy `lib/mysql++.h` over from a released version of MySQL++. While you're doing that, you might copy over the other such generated files: install.hta mysql++.spec doc/userman/userman.dbx lib/Doxyfile Having done that, you can complete the bootstrapping process by running `bootstrap.bat`. It has the same purpose as the Bourne shell script described above, but much simpler. It has none of the command line options described above, for one thing. The main downside of doing it this way is that your changed version will have the same version number as the release of MySQL++ you copied the files from, unless you go into each file and change the version numbers. ### Option 2: Cygwin If you'd like to hack on MySQL++ entirely on Windows and have all the build freedoms enjoyed by those working on Unixy platforms, the simplest solution is probably to install Cygwin. Get [the Cygwin installer](http://cygwin.com/setup-x86_64.exe). (64-bit. A [32-bit installer](http://cygwin.com/setup-x86.exe) is also available.) When you run it, it will walk you through the steps to install Cygwin. Autoconf and Perl 5 aren't installed in Cygwin by default, so when you get to the packages list, be sure to select them. Autoconf is in the Devel category, and Perl 5 in the Interpreters category. You will also need to install the native Windows binary version of [Bakefile](http://bakefile.org/). Don't get the source version and try to build Bakefile under Cygwin; it won't work. The Windows binary version of Bakefile includes an embedded version of Python, so you won't need to install Cygwin's Python. Having done all this, you can follow the Unix bootstrapping instructions in the previous section. ### Option 3: ["Here's a nickel, kid, get yourself a better computer."][dc] Finally, you might have access to a Unixy system, or the ability to set one up. You don't even need a separate physical computer, now that virtual machine techology is free. Given such a machine, you'd do the Fossil checkout of MySQL++ on that machine, then bootstrap it there using the instructions in the previous section, and copy the generated files back to the Windows box. [dc]: http://tomayko.com/writings/that-dilbert-cartoon ## On Manipulating the Build System Source Files One of the things the bootstrapping system described above does is produces various types of project and make files from a small number of source files. This system lets us support many platforms without having to maintain separate build system files for each platform. [Bakefile](http://bakefile.org/) produces most of these project and make files from a single source file called [`mysql++.bkl`][bkl]. Except for small local changes, it's best to change `mysql++.bkl` and "re-bake" the project and make files rather than change those files directly. You can do this with the bootstrap scripts covered above. On Windows, if all you've changed is `mysql++.bkl`, you can use `rebake.bat` instead, which doesn't try to do as much as `bootstrap.bat`. Bakefile produces finished project files for Visual C++ and Xcode and finished `Makefiles` for MinGW. It also produces `Makefile.in`, which is input to GNU Autoconf along with configure.ac and `config/*`. You may need to change these latter files in addition to or instead of `mysql++.bkl` to get the effect you want. Running bootstrap incorporates changes to all of these files in the GNU Autoconf output. While Bakefile's documentation isn't as comprehensive as it ought to be, you can at least count on it to list all of the available features. So, if you can't see a way to make Bakefile do something, it's likely it just can't do it. Bakefile is a high-level abstraction of build systems in general, so it'll never support all the particulars of every odd build system out there. [bkl]: https://tangentsoft.com/mysqlpp/file/mysql%2B%2B.bkl ## Submitting Patches If you wish to submit a patch to the library, please send it to the [MySQL++ mailing list][ml]. We want patches in unified diff format. We will also accept trivial patches not needing discussion as text in a Fossil ticket. The easiest way to get a unified diff is to check out a copy of the current MySQL++ tree as described above. Then make your change, `cd` to the MySQL++ root directory, and ask Fossil to generate the patch for you: $ fossil diff > mychange.patch If your patch adds new files, moves files, or needs to be understood in terms of multiple checkins, it's best to do that work on a [local private branch](#private), then send a [bundle][fb] instead of a patch. If you've sent patches to MySQL++ before and don't have a Fossil developer login, another alternative is to ask for a login before you begin work so that your changes are automatically sync'd to the main Fossil repository as you work, so you don't have to send bundles or patch files. We generally don't refuse such requests if you've already proven your ability to work well with the MySQL++ project. If you're making a patch against a MySQL++ distribution tarball, then you can generate a patch 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/). Fossil is also available for all of these systems. There are no excuses for not being able to make unified diffs. :) [fb]: http://fossil-scm.org/index.html/help?cmd=bundle ## The MySQL++ Code Style Every code base should have a common code style. Love it or hate it, here are MySQL++'s current code style rules: ### Source Code File types: `ac`, `cpp`, `h`, `in`, `m4`, `pl` - Tabs for indents, size 4 - Unix line endings. Any decent programmer's editor can cope with this, even on Windows. - C/C++ rules: - Base whitespace style is AT&Tish: K&R/Stroustrup, plus a little local spice. If you have the indent(1) program, the command is: indent -kr -nce -cli4 -ss -di1 -psl -ts4 FILES... That is, don't cuddle else, indent case statement labels, space before semicolon with empty loop body, no extra space between a variable type and name, return value of function on separate line from rest of definition. - Class names are in `CamelCase`, uppercased first letter - Method names are in `all_lower_case_with_underscores()`; ditto most other global symbols. - Macro names are in `ALL_UPPERCASE_WITH_UNDERSCORES` - Doxygen comment for all public declarations, unless there is a very good reason to keep the thing undocumented. - Perl and shell script rules are more or less the same as for C/C++, to the extent this makes sense. ### XML/HTML Dialects File types: `bkl`, `dbx`, `hta` - Spaces for indents, size 2. Shallow indents due to the high level of nesting occurring in such files, and spaces because they're not as annoying at shallow indent levels in editors that don't treat space indents like tabs. - Unix line endings. Again, these are intended to be viewed in a programmer's text editor, which should work with Unix line endings no matter the platform. ### Plain Text Files File types: `txt` - Spaces for indents, size 4. Spaces because such files are often viewed in Notepad and similarly crippled text editors which use a default indent level of 8. - DOS line endings, again for the Notepad reason. And on modern Unixy platforms, the tools cope with DOS line endings reasonably well. Better than the converse, anyway. When in doubt, mimic what you see in the current code. When still in doubt, ask on the [mailing list][ml]. ## Testing Your Proposed Change MySQL++ includes a self-test mechanism called `dtest`. It's a Bourne shell script, run much like `exrun`: $ ./dtest [-s server_addr] [-u user] [-p password] This automatically runs most of the examples, captures the outputs to a file, and then compares that to a known-good run's outputs, stored in bmark.txt. So, before you submit a patch, run dtest to see if 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 it gives an expected change, remove bmark.txt, re-run dtest, and include the bmark.txt diffs in 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. `dtest` also runs all of the unit tests in `test/*`. The purpose of `test/*` is different from that of `examples/*`: - `test/*` are unit tests: each tests only one MySQL++ class, independent of everything else. Because DB access requires several MySQL++ classes to cooperate, a unit test never accesses a database; hence, no unit test needs DB connection parameters. We will never get 100% code coverage from `test/*` alone. - `examples/*` can be thought of as integration tests: they test many pieces of MySQL++ working together, accessing a real database server. In addition to ensuring that all the pieces work together and give consistent results from platform to platform and run to run, it also fills in gaps in the code coverage where no suitable test/* module could be created. - `test/*` programs always run silently on success, writing output only to indicate test failures. This is because they're usually only run via dtest. - `examples/*` are always "noisy," regardless of whether they succeed or fail, because they're also run interactively by people learning to use MySQL++. Patches should include tests if they introduce new functionality or fix a bug that the existing test coverage failed to catch. If the test is noisy, needs DB access, or tests multiple parts of the library at once, it goes in `examples/*`. If your change affects only one class in MySQL++ and testing it can be done without instantiating other MySQL++ classes -- other than by composition, of course -- it should go in `test/*`. In general, prefer modifying an existing `examples/*` or `test/*` program. Add a new one only if you're introducing brand new functionality or when a given feature currently has no test at all. Beware that the primary role the examples is to illustrate points in the user manual. If an existing example does something similar to what a proper test would need to do and the test doesn't change the nature of the example, don't worry about changing the example code. If your test would change the nature of the example, you either need to do the test another way, or also submit a change to `doc/userman/*.dbx` that incorporates the difference. ## Adding Support for a Different Compiler As described above, 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. ## <a name="private"></a>Maintaining a Private Repository Although Fossil syncs changes back to the `tangentsoft.com/mysqlpp` Fossil repository by default, it is possible to maintain a private copy that simply pulls changes in occasionally. The first step is to turn off the auto-sync feature: $ fossil set autosync 0 Then, I recommend that you make any local changes on a branch: ...hack, hack, hack... $ fossil ci --branch my-local-branch After you give the `--branch` option on a checkin, Fossil automatically switches your local checkout to tht branch, so that all further checkins can be made without the `--branch` option. To get back to the trunk, you'd say `fossil up trunk`, but under this workflow, the need for that will be rare. When something happens on the official trunk on `tangentsoft.com` that you want pulled into your private repository, say: $ fossil sync $ fossil merge trunk The first command pulls all remote changes into your local clone, but since those changes don't affect your private branch, you won't see any immediate change. The second attempts to merge the trunk branch's changes since the last branch or merge point into your private branch. Whether the merge is successful or not, Fossil does not immediately modify your clone, only the working checkout directory. You must then say `fossil ci` once you're happy with the merge. Until then, all the usual Fossil commands like `fossil diff` and `fossil status` will help you come to that decision. If you ever decide to contribute your private branch to the MySQL++ project, there are a couple of easy ways to achieve that. Ask about it on the [mailing list][ml] if you find yourself in this situation. |
Added INSTALL.txt.
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | The installation procedure depends on the compiler you use to build MySQL++ and the OS you build it on. There are platform-specific instructions for all popular platforms: README-Cygwin.txt - for Cygwin README-Linux.txt - for Linux README-Mac-OS-X.txt - for Mac OS X README-MinGW.txt - for MinGW README-Solaris.txt - for Solaris README-Visual-C++.txt - for Visual C++ If you're on some Unix variant (Linux, OS X, *BSD, Solaris, Cygwin...) there are additional general instructions in README-Unix.txt. See the main README.txt file for high-level instructions that apply to all platforms MySQL++ works on. |
Deleted LGPL.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added LICENSE.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | 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! |
Deleted Makefile.am.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added Makefile.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 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 | # ========================================================================= # This makefile was generated by # Bakefile 0.2.9 (http://www.bakefile.org) # Do not modify, all changes will be overwritten! # ========================================================================= # ------------------------------------------------------------------------- # These are configurable options: # ------------------------------------------------------------------------- # Compiler flags to link shared library LINK_DLL_FLAGS ?= -shared # C++ compiler CXX = g++ # Standard flags for C++ CXXFLAGS ?= # Standard preprocessor flags (common for CC and CXX) CPPFLAGS ?= # Standard linker flags LDFLAGS ?= # Type of compiled binaries [debug,release] BUILD ?= debug # ------------------------------------------------------------------------- # Do not modify the rest of this file! # ------------------------------------------------------------------------- ### Variables: ### CPPDEPS = -MT$@ -MF$@.d -MD -MP MYSQLPP_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -mthreads -DUNICODE \ -D_UNICODE -DMYSQLPP_NO_DLL -DHAVE_MYSQL_SSL_SET -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) MYSQLPP_OBJECTS = \ mysqlpp_beemutex.o \ mysqlpp_cmdline.o \ mysqlpp_connection.o \ mysqlpp_cpool.o \ mysqlpp_datetime.o \ mysqlpp_dbdriver.o \ mysqlpp_field_names.o \ mysqlpp_field_types.o \ mysqlpp_manip.o \ mysqlpp_myset.o \ mysqlpp_mysql++.o \ mysqlpp_mystring.o \ mysqlpp_null.o \ mysqlpp_options.o \ mysqlpp_qparms.o \ mysqlpp_query.o \ mysqlpp_result.o \ mysqlpp_row.o \ mysqlpp_scopedconnection.o \ mysqlpp_sql_buffer.o \ mysqlpp_sqlstream.o \ mysqlpp_ssqls2.o \ mysqlpp_stadapter.o \ mysqlpp_tcp_connection.o \ mysqlpp_transaction.o \ mysqlpp_type_info.o \ mysqlpp_uds_connection.o \ mysqlpp_utility.o \ mysqlpp_vallist.o \ mysqlpp_wnp_connection.o SSQLS2PARSE_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" -I. $(CPPFLAGS) $(CXXFLAGS) SSQLS2PARSE_OBJECTS = \ ssqls2parse_parsev2.o SSQLSXLAT_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLSXLAT_OBJECTS = \ ssqlsxlat_genv2.o \ ssqlsxlat_main.o TEST_ARRAY_INDEX_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_ARRAY_INDEX_OBJECTS = \ test_array_index_array_index.o TEST_CPOOL_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_CPOOL_OBJECTS = \ test_cpool_cpool.o TEST_DATETIME_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_DATETIME_OBJECTS = \ test_datetime_datetime.o TEST_INTTYPES_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_INTTYPES_OBJECTS = \ test_inttypes_inttypes.o TEST_INSERTPOLICY_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_INSERTPOLICY_OBJECTS = \ test_insertpolicy_insertpolicy.o TEST_MANIP_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_MANIP_OBJECTS = \ test_manip_manip.o TEST_NULL_COMPARISON_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) \ -Ilib -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_NULL_COMPARISON_OBJECTS = \ test_null_comparison_null_comparison.o TEST_QUERY_COPY_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_QUERY_COPY_OBJECTS = \ test_query_copy_query_copy.o TEST_QSSQLS_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_QSSQLS_OBJECTS = \ test_qssqls_qssqls.o TEST_QSTREAM_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_QSTREAM_OBJECTS = \ test_qstream_qstream.o TEST_SQLSTREAM_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_SQLSTREAM_OBJECTS = \ test_sqlstream_sqlstream.o TEST_SSQLS2_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_SSQLS2_OBJECTS = \ test_ssqls2_ssqls2.o TEST_STRING_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_STRING_OBJECTS = \ test_string_string.o TEST_TCP_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_TCP_OBJECTS = \ test_tcp_tcp.o TEST_UDS_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_UDS_OBJECTS = \ test_uds_uds.o TEST_WNP_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TEST_WNP_OBJECTS = \ test_wnp_wnp.o EXCOMMON_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) EXCOMMON_OBJECTS = \ excommon_printdata.o CGI_JPEG_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) CGI_JPEG_OBJECTS = \ cgi_jpeg_cgi_jpeg.o CPOOL_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) CPOOL_OBJECTS = \ cpool_cpool.o DBINFO_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) DBINFO_OBJECTS = \ dbinfo_dbinfo.o DEADLOCK_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) DEADLOCK_OBJECTS = \ deadlock_deadlock.o FIELDINF_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) FIELDINF_OBJECTS = \ fieldinf_fieldinf.o FOR_EACH_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) FOR_EACH_OBJECTS = \ for_each_for_each.o LOAD_JPEG_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) LOAD_JPEG_OBJECTS = \ load_jpeg_load_jpeg.o MULTIQUERY_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) MULTIQUERY_OBJECTS = \ multiquery_multiquery.o RESETDB_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) RESETDB_OBJECTS = \ resetdb_resetdb.o SIMPLE1_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SIMPLE1_OBJECTS = \ simple1_simple1.o SIMPLE2_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SIMPLE2_OBJECTS = \ simple2_simple2.o SIMPLE3_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SIMPLE3_OBJECTS = \ simple3_simple3.o SSQLS1_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLS1_OBJECTS = \ ssqls1_ssqls1.o SSQLS2_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLS2_OBJECTS = \ ssqls2_ssqls2.o SSQLS3_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLS3_OBJECTS = \ ssqls3_ssqls3.o SSQLS4_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLS4_OBJECTS = \ ssqls4_ssqls4.o SSQLS5_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLS5_OBJECTS = \ ssqls5_ssqls5.o SSQLS6_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) SSQLS6_OBJECTS = \ ssqls6_ssqls6.o STORE_IF_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) STORE_IF_OBJECTS = \ store_if_store_if.o TQUERY1_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TQUERY1_OBJECTS = \ tquery1_tquery1.o TQUERY2_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TQUERY2_OBJECTS = \ tquery2_tquery2.o TQUERY3_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TQUERY3_OBJECTS = \ tquery3_tquery3.o TQUERY4_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TQUERY4_OBJECTS = \ tquery4_tquery4.o TRANSACTION_CXXFLAGS = -mthreads $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -DUNICODE -D_UNICODE -DMYSQLPP_NO_DLL -I"C:\Program \ Files\MySQL\MySQL Connector C 6.1\include" $(CPPFLAGS) $(CXXFLAGS) TRANSACTION_OBJECTS = \ transaction_transaction.o ### Conditionally set variables: ### ifeq ($(BUILD),debug) __OPTIMIZE_FLAG = -O0 endif ifeq ($(BUILD),release) __OPTIMIZE_FLAG = -O2 endif ifeq ($(BUILD),debug) __DEBUGINFO = -g endif ifeq ($(BUILD),release) __DEBUGINFO = endif ### Targets: ### all: mysqlpp.dll libmysqlpp_ssqls2parse.a ssqlsxlat.exe test_array_index.exe test_cpool.exe test_datetime.exe test_inttypes.exe test_insertpolicy.exe test_manip.exe test_null_comparison.exe test_query_copy.exe test_qssqls.exe test_qstream.exe test_sqlstream.exe test_ssqls2.exe test_string.exe test_tcp.exe test_uds.exe test_wnp.exe libmysqlpp_excommon.a cgi_jpeg.exe cpool.exe dbinfo.exe deadlock.exe fieldinf.exe for_each.exe load_jpeg.exe multiquery.exe resetdb.exe simple1.exe simple2.exe simple3.exe ssqls1.exe ssqls2.exe ssqls3.exe ssqls4.exe ssqls5.exe ssqls6.exe store_if.exe tquery1.exe tquery2.exe tquery3.exe tquery4.exe transaction.exe clean: -if exist .\*.o del .\*.o -if exist .\*.d del .\*.d -if exist mysqlpp.dll del mysqlpp.dll -if exist libmysqlpp.a del libmysqlpp.a -if exist libmysqlpp_ssqls2parse.a del libmysqlpp_ssqls2parse.a -if exist ssqlsxlat.exe del ssqlsxlat.exe -if exist test_array_index.exe del test_array_index.exe -if exist test_cpool.exe del test_cpool.exe -if exist test_datetime.exe del test_datetime.exe -if exist test_inttypes.exe del test_inttypes.exe -if exist test_insertpolicy.exe del test_insertpolicy.exe -if exist test_manip.exe del test_manip.exe -if exist test_null_comparison.exe del test_null_comparison.exe -if exist test_query_copy.exe del test_query_copy.exe -if exist test_qssqls.exe del test_qssqls.exe -if exist test_qstream.exe del test_qstream.exe -if exist test_sqlstream.exe del test_sqlstream.exe -if exist test_ssqls2.exe del test_ssqls2.exe -if exist test_string.exe del test_string.exe -if exist test_tcp.exe del test_tcp.exe -if exist test_uds.exe del test_uds.exe -if exist test_wnp.exe del test_wnp.exe -if exist libmysqlpp_excommon.a del libmysqlpp_excommon.a -if exist cgi_jpeg.exe del cgi_jpeg.exe -if exist cpool.exe del cpool.exe -if exist dbinfo.exe del dbinfo.exe -if exist deadlock.exe del deadlock.exe -if exist fieldinf.exe del fieldinf.exe -if exist for_each.exe del for_each.exe -if exist load_jpeg.exe del load_jpeg.exe -if exist multiquery.exe del multiquery.exe -if exist resetdb.exe del resetdb.exe -if exist simple1.exe del simple1.exe -if exist simple2.exe del simple2.exe -if exist simple3.exe del simple3.exe -if exist ssqls1.exe del ssqls1.exe -if exist ssqls2.exe del ssqls2.exe -if exist ssqls3.exe del ssqls3.exe -if exist ssqls4.exe del ssqls4.exe -if exist ssqls5.exe del ssqls5.exe -if exist ssqls6.exe del ssqls6.exe -if exist store_if.exe del store_if.exe -if exist tquery1.exe del tquery1.exe -if exist tquery2.exe del tquery2.exe -if exist tquery3.exe del tquery3.exe -if exist tquery4.exe del tquery4.exe -if exist transaction.exe del transaction.exe mysqlpp.dll: $(MYSQLPP_OBJECTS) $(CXX) $(LINK_DLL_FLAGS) -fPIC -o $@ $(MYSQLPP_OBJECTS) -Wl,--out-implib=libmysqlpp.a $(__DEBUGINFO) -mthreads -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lwsock32 -lmysql libmysqlpp_ssqls2parse.a: $(SSQLS2PARSE_OBJECTS) mysqlpp.dll mysqlpp.dll if exist $@ del $@ ar rcu $@ $(SSQLS2PARSE_OBJECTS) ranlib $@ ssqlsxlat.exe: $(SSQLSXLAT_OBJECTS) mysqlpp.dll libmysqlpp_ssqls2parse.a $(CXX) -o $@ $(SSQLSXLAT_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp -lmysqlpp_ssqls2parse -lmysqlpp test_array_index.exe: $(TEST_ARRAY_INDEX_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_ARRAY_INDEX_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_cpool.exe: $(TEST_CPOOL_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_CPOOL_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_datetime.exe: $(TEST_DATETIME_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_DATETIME_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_inttypes.exe: $(TEST_INTTYPES_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_INTTYPES_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_insertpolicy.exe: $(TEST_INSERTPOLICY_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_INSERTPOLICY_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_manip.exe: $(TEST_MANIP_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_MANIP_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_null_comparison.exe: $(TEST_NULL_COMPARISON_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_NULL_COMPARISON_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_query_copy.exe: $(TEST_QUERY_COPY_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_QUERY_COPY_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_qssqls.exe: $(TEST_QSSQLS_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_QSSQLS_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_qstream.exe: $(TEST_QSTREAM_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_QSTREAM_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_sqlstream.exe: $(TEST_SQLSTREAM_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_SQLSTREAM_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_ssqls2.exe: $(TEST_SSQLS2_OBJECTS) mysqlpp.dll libmysqlpp_ssqls2parse.a $(CXX) -o $@ $(TEST_SSQLS2_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp -lmysqlpp_ssqls2parse -lmysqlpp test_string.exe: $(TEST_STRING_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_STRING_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_tcp.exe: $(TEST_TCP_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_TCP_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_uds.exe: $(TEST_UDS_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_UDS_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp test_wnp.exe: $(TEST_WNP_OBJECTS) mysqlpp.dll $(CXX) -o $@ $(TEST_WNP_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysql -lmysqlpp libmysqlpp_excommon.a: $(EXCOMMON_OBJECTS) mysqlpp.dll if exist $@ del $@ ar rcu $@ $(EXCOMMON_OBJECTS) ranlib $@ cgi_jpeg.exe: $(CGI_JPEG_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(CGI_JPEG_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp cpool.exe: $(CPOOL_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(CPOOL_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp dbinfo.exe: $(DBINFO_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(DBINFO_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp deadlock.exe: $(DEADLOCK_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(DEADLOCK_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp fieldinf.exe: $(FIELDINF_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(FIELDINF_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp for_each.exe: $(FOR_EACH_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(FOR_EACH_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp load_jpeg.exe: $(LOAD_JPEG_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(LOAD_JPEG_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp multiquery.exe: $(MULTIQUERY_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(MULTIQUERY_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp resetdb.exe: $(RESETDB_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(RESETDB_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp simple1.exe: $(SIMPLE1_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SIMPLE1_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp simple2.exe: $(SIMPLE2_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SIMPLE2_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp simple3.exe: $(SIMPLE3_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SIMPLE3_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp ssqls1.exe: $(SSQLS1_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SSQLS1_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp ssqls2.exe: $(SSQLS2_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SSQLS2_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp ssqls3.exe: $(SSQLS3_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SSQLS3_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp ssqls4.exe: $(SSQLS4_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SSQLS4_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp ssqls5.exe: $(SSQLS5_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SSQLS5_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp ssqls6.exe: $(SSQLS6_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(SSQLS6_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp store_if.exe: $(STORE_IF_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(STORE_IF_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp tquery1.exe: $(TQUERY1_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(TQUERY1_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp tquery2.exe: $(TQUERY2_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(TQUERY2_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp tquery3.exe: $(TQUERY3_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(TQUERY3_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp tquery4.exe: $(TQUERY4_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(TQUERY4_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp transaction.exe: $(TRANSACTION_OBJECTS) libmysqlpp_excommon.a mysqlpp.dll $(CXX) -o $@ $(TRANSACTION_OBJECTS) -mthreads $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup -L"C:\Program Files\MySQL\MySQL Connector C 6.1\lib" $(LDFLAGS) -lmysqlpp_excommon -lmysql -lmysqlpp mysqlpp_beemutex.o: ./lib/beemutex.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_cmdline.o: ./lib/cmdline.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_connection.o: ./lib/connection.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_cpool.o: ./lib/cpool.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_datetime.o: ./lib/datetime.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_dbdriver.o: ./lib/dbdriver.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_field_names.o: ./lib/field_names.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_field_types.o: ./lib/field_types.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_manip.o: ./lib/manip.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_myset.o: ./lib/myset.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_mysql++.o: ./lib/mysql++.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_mystring.o: ./lib/mystring.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_null.o: ./lib/null.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_options.o: ./lib/options.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_qparms.o: ./lib/qparms.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_query.o: ./lib/query.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_result.o: ./lib/result.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_row.o: ./lib/row.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_scopedconnection.o: ./lib/scopedconnection.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_sql_buffer.o: ./lib/sql_buffer.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_sqlstream.o: ./lib/sqlstream.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_ssqls2.o: ./lib/ssqls2.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_stadapter.o: ./lib/stadapter.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_tcp_connection.o: ./lib/tcp_connection.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_transaction.o: ./lib/transaction.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_type_info.o: ./lib/type_info.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_uds_connection.o: ./lib/uds_connection.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_utility.o: ./lib/utility.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_vallist.o: ./lib/vallist.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< mysqlpp_wnp_connection.o: ./lib/wnp_connection.cpp $(CXX) -c -o $@ $(MYSQLPP_CXXFLAGS) $(CPPDEPS) $< ssqls2parse_parsev2.o: ./ssx/parsev2.cpp $(CXX) -c -o $@ $(SSQLS2PARSE_CXXFLAGS) $(CPPDEPS) $< ssqlsxlat_genv2.o: ./ssx/genv2.cpp $(CXX) -c -o $@ $(SSQLSXLAT_CXXFLAGS) $(CPPDEPS) $< ssqlsxlat_main.o: ./ssx/main.cpp $(CXX) -c -o $@ $(SSQLSXLAT_CXXFLAGS) $(CPPDEPS) $< test_array_index_array_index.o: ./test/array_index.cpp $(CXX) -c -o $@ $(TEST_ARRAY_INDEX_CXXFLAGS) $(CPPDEPS) $< test_cpool_cpool.o: ./test/cpool.cpp $(CXX) -c -o $@ $(TEST_CPOOL_CXXFLAGS) $(CPPDEPS) $< test_datetime_datetime.o: ./test/datetime.cpp $(CXX) -c -o $@ $(TEST_DATETIME_CXXFLAGS) $(CPPDEPS) $< test_inttypes_inttypes.o: ./test/inttypes.cpp $(CXX) -c -o $@ $(TEST_INTTYPES_CXXFLAGS) $(CPPDEPS) $< test_insertpolicy_insertpolicy.o: ./test/insertpolicy.cpp $(CXX) -c -o $@ $(TEST_INSERTPOLICY_CXXFLAGS) $(CPPDEPS) $< test_manip_manip.o: ./test/manip.cpp $(CXX) -c -o $@ $(TEST_MANIP_CXXFLAGS) $(CPPDEPS) $< test_null_comparison_null_comparison.o: ./test/null_comparison.cpp $(CXX) -c -o $@ $(TEST_NULL_COMPARISON_CXXFLAGS) $(CPPDEPS) $< test_query_copy_query_copy.o: ./test/query_copy.cpp $(CXX) -c -o $@ $(TEST_QUERY_COPY_CXXFLAGS) $(CPPDEPS) $< test_qssqls_qssqls.o: ./test/qssqls.cpp $(CXX) -c -o $@ $(TEST_QSSQLS_CXXFLAGS) $(CPPDEPS) $< test_qstream_qstream.o: ./test/qstream.cpp $(CXX) -c -o $@ $(TEST_QSTREAM_CXXFLAGS) $(CPPDEPS) $< test_sqlstream_sqlstream.o: ./test/sqlstream.cpp $(CXX) -c -o $@ $(TEST_SQLSTREAM_CXXFLAGS) $(CPPDEPS) $< test_ssqls2_ssqls2.o: ./test/ssqls2.cpp $(CXX) -c -o $@ $(TEST_SSQLS2_CXXFLAGS) $(CPPDEPS) $< test_string_string.o: ./test/string.cpp $(CXX) -c -o $@ $(TEST_STRING_CXXFLAGS) $(CPPDEPS) $< test_tcp_tcp.o: ./test/tcp.cpp $(CXX) -c -o $@ $(TEST_TCP_CXXFLAGS) $(CPPDEPS) $< test_uds_uds.o: ./test/uds.cpp $(CXX) -c -o $@ $(TEST_UDS_CXXFLAGS) $(CPPDEPS) $< test_wnp_wnp.o: ./test/wnp.cpp $(CXX) -c -o $@ $(TEST_WNP_CXXFLAGS) $(CPPDEPS) $< excommon_printdata.o: ./examples/printdata.cpp $(CXX) -c -o $@ $(EXCOMMON_CXXFLAGS) $(CPPDEPS) $< cgi_jpeg_cgi_jpeg.o: ./examples/cgi_jpeg.cpp $(CXX) -c -o $@ $(CGI_JPEG_CXXFLAGS) $(CPPDEPS) $< cpool_cpool.o: ./examples/cpool.cpp $(CXX) -c -o $@ $(CPOOL_CXXFLAGS) $(CPPDEPS) $< dbinfo_dbinfo.o: ./examples/dbinfo.cpp $(CXX) -c -o $@ $(DBINFO_CXXFLAGS) $(CPPDEPS) $< deadlock_deadlock.o: ./examples/deadlock.cpp $(CXX) -c -o $@ $(DEADLOCK_CXXFLAGS) $(CPPDEPS) $< fieldinf_fieldinf.o: ./examples/fieldinf.cpp $(CXX) -c -o $@ $(FIELDINF_CXXFLAGS) $(CPPDEPS) $< for_each_for_each.o: ./examples/for_each.cpp $(CXX) -c -o $@ $(FOR_EACH_CXXFLAGS) $(CPPDEPS) $< load_jpeg_load_jpeg.o: ./examples/load_jpeg.cpp $(CXX) -c -o $@ $(LOAD_JPEG_CXXFLAGS) $(CPPDEPS) $< multiquery_multiquery.o: ./examples/multiquery.cpp $(CXX) -c -o $@ $(MULTIQUERY_CXXFLAGS) $(CPPDEPS) $< resetdb_resetdb.o: ./examples/resetdb.cpp $(CXX) -c -o $@ $(RESETDB_CXXFLAGS) $(CPPDEPS) $< simple1_simple1.o: ./examples/simple1.cpp $(CXX) -c -o $@ $(SIMPLE1_CXXFLAGS) $(CPPDEPS) $< simple2_simple2.o: ./examples/simple2.cpp $(CXX) -c -o $@ $(SIMPLE2_CXXFLAGS) $(CPPDEPS) $< simple3_simple3.o: ./examples/simple3.cpp $(CXX) -c -o $@ $(SIMPLE3_CXXFLAGS) $(CPPDEPS) $< ssqls1_ssqls1.o: ./examples/ssqls1.cpp $(CXX) -c -o $@ $(SSQLS1_CXXFLAGS) $(CPPDEPS) $< ssqls2_ssqls2.o: ./examples/ssqls2.cpp $(CXX) -c -o $@ $(SSQLS2_CXXFLAGS) $(CPPDEPS) $< ssqls3_ssqls3.o: ./examples/ssqls3.cpp $(CXX) -c -o $@ $(SSQLS3_CXXFLAGS) $(CPPDEPS) $< ssqls4_ssqls4.o: ./examples/ssqls4.cpp $(CXX) -c -o $@ $(SSQLS4_CXXFLAGS) $(CPPDEPS) $< ssqls5_ssqls5.o: ./examples/ssqls5.cpp $(CXX) -c -o $@ $(SSQLS5_CXXFLAGS) $(CPPDEPS) $< ssqls6_ssqls6.o: ./examples/ssqls6.cpp $(CXX) -c -o $@ $(SSQLS6_CXXFLAGS) $(CPPDEPS) $< store_if_store_if.o: ./examples/store_if.cpp $(CXX) -c -o $@ $(STORE_IF_CXXFLAGS) $(CPPDEPS) $< tquery1_tquery1.o: ./examples/tquery1.cpp $(CXX) -c -o $@ $(TQUERY1_CXXFLAGS) $(CPPDEPS) $< tquery2_tquery2.o: ./examples/tquery2.cpp $(CXX) -c -o $@ $(TQUERY2_CXXFLAGS) $(CPPDEPS) $< tquery3_tquery3.o: ./examples/tquery3.cpp $(CXX) -c -o $@ $(TQUERY3_CXXFLAGS) $(CPPDEPS) $< tquery4_tquery4.o: ./examples/tquery4.cpp $(CXX) -c -o $@ $(TQUERY4_CXXFLAGS) $(CPPDEPS) $< transaction_transaction.o: ./examples/transaction.cpp $(CXX) -c -o $@ $(TRANSACTION_CXXFLAGS) $(CPPDEPS) $< .PHONY: all clean SHELL := $(COMSPEC) # Dependencies tracking: -include ./*.d |
Added Makefile.simple.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | # ========================================================================= # This makefile was generated by # Bakefile 0.2.9 (http://www.bakefile.org) # Do not modify, all changes will be overwritten! # ========================================================================= # ------------------------------------------------------------------------- # These are configurable options: # ------------------------------------------------------------------------- # AR ?= ar # RANLIB ?= ranlib # C++ compiler CXX = g++ # Standard flags for C++ CXXFLAGS ?= # Standard preprocessor flags (common for CC and CXX) CPPFLAGS ?= # Standard linker flags LDFLAGS ?= # Type of compiled binaries [debug,release] BUILD ?= debug # ------------------------------------------------------------------------- # Do not modify the rest of this file! # ------------------------------------------------------------------------- ### Variables: ### CPPDEPS = -MT$@ -MF`echo $@ | sed -e 's,\.o$$,.d,'` -MD -MP TEST_ARRAY_INDEX_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_ARRAY_INDEX_OBJECTS = \ test_array_index_array_index.o TEST_CPOOL_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_CPOOL_OBJECTS = \ test_cpool_cpool.o TEST_DATETIME_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_DATETIME_OBJECTS = \ test_datetime_datetime.o TEST_INTTYPES_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_INTTYPES_OBJECTS = \ test_inttypes_inttypes.o TEST_INSERTPOLICY_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_INSERTPOLICY_OBJECTS = \ test_insertpolicy_insertpolicy.o TEST_MANIP_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_MANIP_OBJECTS = \ test_manip_manip.o TEST_NULL_COMPARISON_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_NULL_COMPARISON_OBJECTS = \ test_null_comparison_null_comparison.o TEST_QUERY_COPY_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_QUERY_COPY_OBJECTS = \ test_query_copy_query_copy.o TEST_QSSQLS_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_QSSQLS_OBJECTS = \ test_qssqls_qssqls.o TEST_QSTREAM_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_QSTREAM_OBJECTS = \ test_qstream_qstream.o TEST_SQLSTREAM_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_SQLSTREAM_OBJECTS = \ test_sqlstream_sqlstream.o TEST_STRING_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TEST_STRING_OBJECTS = \ test_string_string.o TEST_TCP_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TEST_TCP_OBJECTS = \ test_tcp_tcp.o TEST_UDS_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TEST_UDS_OBJECTS = \ test_uds_uds.o TEST_WNP_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TEST_WNP_OBJECTS = \ test_wnp_wnp.o EXCOMMON_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) EXCOMMON_OBJECTS = \ excommon_printdata.o CGI_JPEG_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) CGI_JPEG_OBJECTS = \ cgi_jpeg_cgi_jpeg.o CPOOL_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) CPOOL_OBJECTS = \ cpool_cpool.o DBINFO_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) DBINFO_OBJECTS = \ dbinfo_dbinfo.o DEADLOCK_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) DEADLOCK_OBJECTS = \ deadlock_deadlock.o FIELDINF_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) FIELDINF_OBJECTS = \ fieldinf_fieldinf.o FOR_EACH_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) FOR_EACH_OBJECTS = \ for_each_for_each.o LOAD_JPEG_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) LOAD_JPEG_OBJECTS = \ load_jpeg_load_jpeg.o MULTIQUERY_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) MULTIQUERY_OBJECTS = \ multiquery_multiquery.o RESETDB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) RESETDB_OBJECTS = \ resetdb_resetdb.o SIMPLE1_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SIMPLE1_OBJECTS = \ simple1_simple1.o SIMPLE2_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SIMPLE2_OBJECTS = \ simple2_simple2.o SIMPLE3_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SIMPLE3_OBJECTS = \ simple3_simple3.o SSQLS1_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SSQLS1_OBJECTS = \ ssqls1_ssqls1.o SSQLS2_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SSQLS2_OBJECTS = \ ssqls2_ssqls2.o SSQLS3_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SSQLS3_OBJECTS = \ ssqls3_ssqls3.o SSQLS4_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SSQLS4_OBJECTS = \ ssqls4_ssqls4.o SSQLS5_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SSQLS5_OBJECTS = \ ssqls5_ssqls5.o SSQLS6_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) SSQLS6_OBJECTS = \ ssqls6_ssqls6.o STORE_IF_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) STORE_IF_OBJECTS = \ store_if_store_if.o TQUERY1_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TQUERY1_OBJECTS = \ tquery1_tquery1.o TQUERY2_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TQUERY2_OBJECTS = \ tquery2_tquery2.o TQUERY3_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TQUERY3_OBJECTS = \ tquery3_tquery3.o TQUERY4_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib -I@MYSQL_C_INC_DIR@ \ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) $(CXXFLAGS) TQUERY4_OBJECTS = \ tquery4_tquery4.o TRANSACTION_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZE_FLAG) -Ilib \ -I@MYSQL_C_INC_DIR@ -I/usr/include/mysql -I/usr/include/mysql++ $(CPPFLAGS) \ $(CXXFLAGS) TRANSACTION_OBJECTS = \ transaction_transaction.o ### Conditionally set variables: ### ifeq ($(BUILD),debug) __OPTIMIZE_FLAG = -O0 endif ifeq ($(BUILD),release) __OPTIMIZE_FLAG = -O2 endif ifeq ($(BUILD),debug) __DEBUGINFO = -g endif ifeq ($(BUILD),release) __DEBUGINFO = endif ### Targets: ### all: test_array_index test_cpool test_datetime test_inttypes test_insertpolicy test_manip test_null_comparison test_query_copy test_qssqls test_qstream test_sqlstream test_string test_tcp test_uds test_wnp libmysqlpp_excommon.a cgi_jpeg cpool dbinfo deadlock fieldinf for_each load_jpeg multiquery resetdb simple1 simple2 simple3 ssqls1 ssqls2 ssqls3 ssqls4 ssqls5 ssqls6 store_if tquery1 tquery2 tquery3 tquery4 transaction install: uninstall: clean: rm -f ./*.o rm -f ./*.d rm -f test_array_index rm -f test_cpool rm -f test_datetime rm -f test_inttypes rm -f test_insertpolicy rm -f test_manip rm -f test_null_comparison rm -f test_query_copy rm -f test_qssqls rm -f test_qstream rm -f test_sqlstream rm -f test_string rm -f test_tcp rm -f test_uds rm -f test_wnp rm -f libmysqlpp_excommon.a rm -f cgi_jpeg rm -f cpool rm -f dbinfo rm -f deadlock rm -f fieldinf rm -f for_each rm -f load_jpeg rm -f multiquery rm -f resetdb rm -f simple1 rm -f simple2 rm -f simple3 rm -f ssqls1 rm -f ssqls2 rm -f ssqls3 rm -f ssqls4 rm -f ssqls5 rm -f ssqls6 rm -f store_if rm -f tquery1 rm -f tquery2 rm -f tquery3 rm -f tquery4 rm -f transaction test_array_index: $(TEST_ARRAY_INDEX_OBJECTS) $(CXX) -o $@ $(TEST_ARRAY_INDEX_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_cpool: $(TEST_CPOOL_OBJECTS) $(CXX) -o $@ $(TEST_CPOOL_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_datetime: $(TEST_DATETIME_OBJECTS) $(CXX) -o $@ $(TEST_DATETIME_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_inttypes: $(TEST_INTTYPES_OBJECTS) $(CXX) -o $@ $(TEST_INTTYPES_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_insertpolicy: $(TEST_INSERTPOLICY_OBJECTS) $(CXX) -o $@ $(TEST_INSERTPOLICY_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_manip: $(TEST_MANIP_OBJECTS) $(CXX) -o $@ $(TEST_MANIP_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_null_comparison: $(TEST_NULL_COMPARISON_OBJECTS) $(CXX) -o $@ $(TEST_NULL_COMPARISON_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_query_copy: $(TEST_QUERY_COPY_OBJECTS) $(CXX) -o $@ $(TEST_QUERY_COPY_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_qssqls: $(TEST_QSSQLS_OBJECTS) $(CXX) -o $@ $(TEST_QSSQLS_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_qstream: $(TEST_QSTREAM_OBJECTS) $(CXX) -o $@ $(TEST_QSTREAM_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_sqlstream: $(TEST_SQLSTREAM_OBJECTS) $(CXX) -o $@ $(TEST_SQLSTREAM_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_string: $(TEST_STRING_OBJECTS) $(CXX) -o $@ $(TEST_STRING_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_tcp: $(TEST_TCP_OBJECTS) $(CXX) -o $@ $(TEST_TCP_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_uds: $(TEST_UDS_OBJECTS) $(CXX) -o $@ $(TEST_UDS_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient test_wnp: $(TEST_WNP_OBJECTS) $(CXX) -o $@ $(TEST_WNP_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp -lmysqlclient libmysqlpp_excommon.a: $(EXCOMMON_OBJECTS) rm -f $@ $(AR) rcu $@ $(EXCOMMON_OBJECTS) $(RANLIB) $@ cgi_jpeg: $(CGI_JPEG_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(CGI_JPEG_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient cpool: $(CPOOL_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(CPOOL_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient dbinfo: $(DBINFO_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(DBINFO_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient deadlock: $(DEADLOCK_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(DEADLOCK_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient fieldinf: $(FIELDINF_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(FIELDINF_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient for_each: $(FOR_EACH_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(FOR_EACH_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient load_jpeg: $(LOAD_JPEG_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(LOAD_JPEG_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient multiquery: $(MULTIQUERY_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(MULTIQUERY_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient resetdb: $(RESETDB_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(RESETDB_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient simple1: $(SIMPLE1_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SIMPLE1_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient simple2: $(SIMPLE2_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SIMPLE2_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient simple3: $(SIMPLE3_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SIMPLE3_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient ssqls1: $(SSQLS1_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SSQLS1_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient ssqls2: $(SSQLS2_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SSQLS2_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient ssqls3: $(SSQLS3_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SSQLS3_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient ssqls4: $(SSQLS4_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SSQLS4_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient ssqls5: $(SSQLS5_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SSQLS5_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient ssqls6: $(SSQLS6_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(SSQLS6_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient store_if: $(STORE_IF_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(STORE_IF_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient tquery1: $(TQUERY1_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(TQUERY1_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient tquery2: $(TQUERY2_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(TQUERY2_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient tquery3: $(TQUERY3_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(TQUERY3_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient tquery4: $(TQUERY4_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(TQUERY4_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient transaction: $(TRANSACTION_OBJECTS) libmysqlpp_excommon.a $(CXX) -o $@ $(TRANSACTION_OBJECTS) $(__DEBUGINFO) -L@MYSQL_C_LIB_DIR@ -L. $(LDFLAGS) -lmysqlpp_excommon -lmysqlpp -lmysqlclient test_array_index_array_index.o: ./test/array_index.cpp $(CXX) -c -o $@ $(TEST_ARRAY_INDEX_CXXFLAGS) $(CPPDEPS) $< test_cpool_cpool.o: ./test/cpool.cpp $(CXX) -c -o $@ $(TEST_CPOOL_CXXFLAGS) $(CPPDEPS) $< test_datetime_datetime.o: ./test/datetime.cpp $(CXX) -c -o $@ $(TEST_DATETIME_CXXFLAGS) $(CPPDEPS) $< test_inttypes_inttypes.o: ./test/inttypes.cpp $(CXX) -c -o $@ $(TEST_INTTYPES_CXXFLAGS) $(CPPDEPS) $< test_insertpolicy_insertpolicy.o: ./test/insertpolicy.cpp $(CXX) -c -o $@ $(TEST_INSERTPOLICY_CXXFLAGS) $(CPPDEPS) $< test_manip_manip.o: ./test/manip.cpp $(CXX) -c -o $@ $(TEST_MANIP_CXXFLAGS) $(CPPDEPS) $< test_null_comparison_null_comparison.o: ./test/null_comparison.cpp $(CXX) -c -o $@ $(TEST_NULL_COMPARISON_CXXFLAGS) $(CPPDEPS) $< test_query_copy_query_copy.o: ./test/query_copy.cpp $(CXX) -c -o $@ $(TEST_QUERY_COPY_CXXFLAGS) $(CPPDEPS) $< test_qssqls_qssqls.o: ./test/qssqls.cpp $(CXX) -c -o $@ $(TEST_QSSQLS_CXXFLAGS) $(CPPDEPS) $< test_qstream_qstream.o: ./test/qstream.cpp $(CXX) -c -o $@ $(TEST_QSTREAM_CXXFLAGS) $(CPPDEPS) $< test_sqlstream_sqlstream.o: ./test/sqlstream.cpp $(CXX) -c -o $@ $(TEST_SQLSTREAM_CXXFLAGS) $(CPPDEPS) $< test_string_string.o: ./test/string.cpp $(CXX) -c -o $@ $(TEST_STRING_CXXFLAGS) $(CPPDEPS) $< test_tcp_tcp.o: ./test/tcp.cpp $(CXX) -c -o $@ $(TEST_TCP_CXXFLAGS) $(CPPDEPS) $< test_uds_uds.o: ./test/uds.cpp $(CXX) -c -o $@ $(TEST_UDS_CXXFLAGS) $(CPPDEPS) $< test_wnp_wnp.o: ./test/wnp.cpp $(CXX) -c -o $@ $(TEST_WNP_CXXFLAGS) $(CPPDEPS) $< excommon_printdata.o: ./examples/printdata.cpp $(CXX) -c -o $@ $(EXCOMMON_CXXFLAGS) $(CPPDEPS) $< cgi_jpeg_cgi_jpeg.o: ./examples/cgi_jpeg.cpp $(CXX) -c -o $@ $(CGI_JPEG_CXXFLAGS) $(CPPDEPS) $< cpool_cpool.o: ./examples/cpool.cpp $(CXX) -c -o $@ $(CPOOL_CXXFLAGS) $(CPPDEPS) $< dbinfo_dbinfo.o: ./examples/dbinfo.cpp $(CXX) -c -o $@ $(DBINFO_CXXFLAGS) $(CPPDEPS) $< deadlock_deadlock.o: ./examples/deadlock.cpp $(CXX) -c -o $@ $(DEADLOCK_CXXFLAGS) $(CPPDEPS) $< fieldinf_fieldinf.o: ./examples/fieldinf.cpp $(CXX) -c -o $@ $(FIELDINF_CXXFLAGS) $(CPPDEPS) $< for_each_for_each.o: ./examples/for_each.cpp $(CXX) -c -o $@ $(FOR_EACH_CXXFLAGS) $(CPPDEPS) $< load_jpeg_load_jpeg.o: ./examples/load_jpeg.cpp $(CXX) -c -o $@ $(LOAD_JPEG_CXXFLAGS) $(CPPDEPS) $< multiquery_multiquery.o: ./examples/multiquery.cpp $(CXX) -c -o $@ $(MULTIQUERY_CXXFLAGS) $(CPPDEPS) $< resetdb_resetdb.o: ./examples/resetdb.cpp $(CXX) -c -o $@ $(RESETDB_CXXFLAGS) $(CPPDEPS) $< simple1_simple1.o: ./examples/simple1.cpp $(CXX) -c -o $@ $(SIMPLE1_CXXFLAGS) $(CPPDEPS) $< simple2_simple2.o: ./examples/simple2.cpp $(CXX) -c -o $@ $(SIMPLE2_CXXFLAGS) $(CPPDEPS) $< simple3_simple3.o: ./examples/simple3.cpp $(CXX) -c -o $@ $(SIMPLE3_CXXFLAGS) $(CPPDEPS) $< ssqls1_ssqls1.o: ./examples/ssqls1.cpp $(CXX) -c -o $@ $(SSQLS1_CXXFLAGS) $(CPPDEPS) $< ssqls2_ssqls2.o: ./examples/ssqls2.cpp $(CXX) -c -o $@ $(SSQLS2_CXXFLAGS) $(CPPDEPS) $< ssqls3_ssqls3.o: ./examples/ssqls3.cpp $(CXX) -c -o $@ $(SSQLS3_CXXFLAGS) $(CPPDEPS) $< ssqls4_ssqls4.o: ./examples/ssqls4.cpp $(CXX) -c -o $@ $(SSQLS4_CXXFLAGS) $(CPPDEPS) $< ssqls5_ssqls5.o: ./examples/ssqls5.cpp $(CXX) -c -o $@ $(SSQLS5_CXXFLAGS) $(CPPDEPS) $< ssqls6_ssqls6.o: ./examples/ssqls6.cpp $(CXX) -c -o $@ $(SSQLS6_CXXFLAGS) $(CPPDEPS) $< store_if_store_if.o: ./examples/store_if.cpp $(CXX) -c -o $@ $(STORE_IF_CXXFLAGS) $(CPPDEPS) $< tquery1_tquery1.o: ./examples/tquery1.cpp $(CXX) -c -o $@ $(TQUERY1_CXXFLAGS) $(CPPDEPS) $< tquery2_tquery2.o: ./examples/tquery2.cpp $(CXX) -c -o $@ $(TQUERY2_CXXFLAGS) $(CPPDEPS) $< tquery3_tquery3.o: ./examples/tquery3.cpp $(CXX) -c -o $@ $(TQUERY3_CXXFLAGS) $(CPPDEPS) $< tquery4_tquery4.o: ./examples/tquery4.cpp $(CXX) -c -o $@ $(TQUERY4_CXXFLAGS) $(CPPDEPS) $< transaction_transaction.o: ./examples/transaction.cpp $(CXX) -c -o $@ $(TRANSACTION_CXXFLAGS) $(CPPDEPS) $< .PHONY: all install uninstall clean # Dependencies tracking: -include ./*.d |
Deleted README.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added README-Cygwin.txt.
> > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Prerequisite: Install MySQL ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before you can build MySQL++, you need to install the libmysqlclient-devel package with Cygwin's setup.exe. In the past, you had to build MySQL from source, since there was no reliable place to get a binary version of the client library for Cygwin. If you must still do this for some reason, here's a hint on how to build just the client library, since you probably will be running either a native Windows version of the server, or have the server installed on another machine entirely: $ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \ --infodir=/usr/share/info --mandir=/usr/share/man \ --disable-shared --without-{debug,readline,libedit,server} Building the Library and Example Programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Having done that, Cygwin behaves like any other Unixy system. See the instructions in README-Unix.txt. |
Added README-Linux.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | Linux is basically Unix, so README-Unix.txt covers the generic bits. I'll just cover a few of the issues specific to Linux here. Prerequisite: Install the MySQL Development Files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MySQL++ is built on top of the MySQL C API library, so it needs the C API development files to build against. Most distributions of the MySQL server for Linux don't come with these development files; they're packaged separately. This is because you don't actually need the server on your development machine, though it's often more convenient to use a local server than a remote one, for testing. There are about as many different ways to get the C API development files on your system as there are major Linux distributions. More actually, because you also have the option of the official MySQL binaries from mysql.com: http://dev.mysql.com/downloads/mysql/5.0.html#linux For RPM-based distributions, MySQL comes in several different packages. You need at least the -devel and the -shared packages to build MySQL++. The other binary distributions seem to come in just a single file, presumably with everything included. You can also build from source, in which case you will also get the entire kit and kaboodle. MySQL frequently comes with Linux distributions as well. If your distribution doesn't come with at least MySQL v4.1, I recommend using the official MySQL.com packages instead. MySQL++ can be made to run with 4.0 and older, but it takes some work. On Red Hat type systems with yum, say: # yum install mysql-devel If you want to use rpm directly, you need that package and probably the base mysql package as well. On Debian/Ubuntu type systems, say: $ sudo apt-get install libmysqlclient15-dev The version number is the ABI version of the MySQL C API library. ABI version 15 corresponds to MySQL version 5.0, the recommended stable version as of this writing. Dealing with the Dynamic Linker, ld.so ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ld.so is a system-level program on Linux which is used to run any program that uses shared libraries (lib*.so). Its job is to find the libraries and link them to the base executable so it will run. Because ld.so only looks in a few places for libraries on most systems, a common problem is a program that builds without error but won't run, complaining about libmysqlpp.SOMETHING. There are a number of ways to deal with this. First, you could just configure MySQL++ to install under /usr instead of /usr/local, like system-provided packages: $ ./configure --prefix=/usr This isn't recommended practice when building packages from source, but it does work. Second, you can add the MySQL++ library directory to the LD_LIBRARY_PATH environment variable. This works like the shell's PATH variable: a colon-separated list of directories to search. This is best when the installation directory is something totally uncommon, or you don't have root permissions on the box so you can't do the next option. Finally, the most robust way to tell ld.so about a nonstandard library directory is to put it in /etc/ld.so.conf or in one of the files included from there. Then, run ldconfig as root to rebuild the cache file ld.so uses to find libraries in these nonstandard directories. Running ldconfig isn't necessary for the previous two methods. |
Added README-Mac-OS-X.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | Building MySQL++ ~~~~~~~~~~~~~~~~ There are two major ways to build MySQL++: from the command line, or from within the Xcode IDE. MySQL++ has its roots in Unix and Linux, like MySQL itself. As a result, the most well-supported way to build MySQL++ is from the command line, or Terminal as Apple likes to call it. See README-Unix.txt for the generic instructions. Further Mac-specific details are given elsewhere in this file. The option to build MySQL++ from within Xcode is new. We added experimental support for it in 3.0.0, but it didn't actually get tested and debugged until 3.1.0. It may still be buggy, and over time it's more likely to break again than the command line method, simply because it receives less testing during development. Even fully functional, it is less flexible than building from the command line; Xcode's project system cannot match the power available within the autotools build system. If you try the Xcode method and find that it doesn't work, the easiest way around that roadblock is to build from the command line instead. If you're the adventurous sort and want to contribute to the development of MySQL++, see the file HACKERS.txt for more info on fixing the source file used as input in the project file generation process. We don't want fixed project files, we want a process that lets us consistently generate correct project files. Prerequisite: Install the MySQL Development Files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MySQL++ is built on top of the MySQL C API library, so for MySQL++ to build, it needs at least that library and its header files installed. You don't need the server itself installed on your development machine, though it's often helpful anyway, for testing. There are many suitable sources: - The simplest option is to download the MySQL server DMG from mysql.com. In addition to the C API files you absolultely must have, this gives you a nice Mac-like installation procedure and a preference pane for bringing the server up and down and setting it to start on system boot. - If you really only want the C API development files, MySQL offers them separately as Connector/C. As of this writing, you get the files as a tarball, and you have to copy its contents to some suitable location on your hard drive. If you're using Xcode to build MySQL++, you'll want to put them under /usr/local/mysql. MySQL++'s command line build system is far more tolerant, looking there and in many other typical locations. - If you use Fink, you can install the C API files with: $ fink install mysql15-dev If you also want a local MySQL server, say this instead: $ fink install mysql mysql15-dev - From MacPorts, http://macports.org. I have zero information on this other than that it's theoretically possible for it to work. If you figure out how to make it work, please post the method to the mailing list so I can update this document. Dealing with the 64-Bit Transition in Snow Leopard ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Xcode for Snow Leopard installs two independent versions of the GNU Compiler Collection. The default is GCC 4.2, and it is set up to build 64-bit executables by default, even if your system is booted into 32-bit mode. You also get GCC 4.0, which builds 32-bit executables by default. On top of that, you have the confusion added by Apple's decision to make all 64-bit capable machines boot into 32-bit mode by default, except for the Xserves. The first symptom most people run into as a result of this mess is that the "configure" script fails, yelling something about being unable to link to libmysqlclient, the MySQL C API client library. It's because the library was probably built as a 32-bit executable and you're using the default compiler which tries to build a 64-bit test executable against this library and fails. There are many ways out of this tarpit. Here are the ones I prefer: First, you can force GCC 4.2 to build 32-bit binaries: ./configure CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 --other-flags-here Second, you can make the MySQL++ build system use GCC 4.0 instead: ./configure CC=gcc-4.0 CXX=g++-4.0 --other-flags-here Last, you could just take Apple's implied advice and start booting your Mac into 64-bit mode, if it will support it. Here's an article that goes into all the details: http://macperformanceguide.com/SnowLeopard-64bit.html I'm aware of other solutions to the problem, but I expect one among these will work for you. Making Universal Binaries ~~~~~~~~~~~~~~~~~~~~~~~~~ By default, the command line build system will generate libraries that only work with the platform you build MySQL++ on. It can be convinced to build "universal" binaries instead by configuring the library like so: $ ./configure --disable-dependency-tracking \ CXXFLAGS='-arch ppc -arch i386' This builds the library for the two 32-bit OS X architectures, and is what most people have traditionally thought of as "universal". However, you may also want a 64-bit build, meaning there are four different architectures, and thus four -arch flags needed: $ ./configure --disable-dependency-tracking \ CXXFLAGS='-arch ppc -arch ppc64 -arch i386 -arch x86_64' These are single commands, with the line broken to keep the line lengths in this document reasonable. The first command doubles build time relative to the default configuration, and the second quadruples it. It also makes the resulting binaries larger, which increases the amount of time it takes to start a program. Build MySQL++ like this only if you must. The --disable-dependency-tracking flag is necessary because, when building universal binaries, it has to rebuild each source module multiple times, which confuses the logic that tries to tell when a given module needs rebuiding based on its dependencies on other files. |
Added README-MinGW.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | Prerequisite: GCC Version ~~~~~~~~~~~~~~~~~~~~~~~~~ If your MinGW version isn't using at least GCC 3.4.5, it needs to be updated. Older versions are known to not work with MySQL++. As of MySQL++ 3.1.1, the required version might need to be even newer, as we are now depending on improvements to the MinGW linker which probably don't go back that far. Prerequisite: MySQL C Development Files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MySQL++ is built atop MySQL's C API library. The easiest way to get that is to install Connector/C on your development system, which you can download from mysql.com. The distribution assumes these files are in: C:\Program Files\MySQL\MySQL Connector C 6.1\ There are a number of reasons why that path may not work for you: - You have a newer version of Connector/C installed - You're on a 64-bit system, but have the 32-bit versions of Connector/C and MinGW installed and wish to build a 32-bit binary. In that case, the path will look like this instead: C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\ - You may have the MySQL Server on your system and installed the development files along with it, and therefore don't want to install Connector/C separately. In that case, the path will look like this instead: C:\Program Files\MySQL\MySQL Server 5.6\ Regardless of the reason you have for changing this path, there are two ways that work: - The easy way is to do a global search and replace on the path in Makefile.mingw. This is a generated file, but if that's the only change to MySQL++ you need, it works fine. - If you're doing deeper work on MySQL++, you should change the MYSQL_WIN_DIR variable at the top of mysql++.bkl instead. Having done that, you can generate Makefile.mingw from that file using the Windows port of Bakefile (http://bakefile.org/): bakefile_gen -f mingw Building the Library and Example Programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ With the prerequisites above taken care of, 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. Many things will break otherwise: path separator handling, shell commands used by the Makefile, etc. Speaking of Cygwin and MSYS, if you have either these or any other Unix emulation environment installed, be sure their executables aren't in the PATH when building MySQL++. MinGW's version of GNU make does some funny things if it thinks it's running in the presence of Unixy tools, which will break the MySQL++ build. Once the library is built, you should run the examples. At minimum, run resetdb and simple1. Once you're satisfied that the library is working correctly, you can run install.hta to automatically install the library files and headers in subdirectories under c:\mysql++. Cygwin and MinGW Coexistence ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's possible to have both Cygwin and MinGW installed and build with the MinGW tools without interference from the Cygwin bits. The main thing you have to take care of is that MinGW's bin directory must precede the Cygwin bin directory in the PATH, so that its tools are found first. If you use Cygwin's bash as a command shell in preference to the DOS-like cmd.exe, you can use this shell script to temporarily set the environment to "MinGW mode" and make it easy to get back to "Cygwin mode": #!/bin/sh PATH=/c/mingw/bin:/c/windows:/c/windows/system32:/c/cygwin/bin echo "Say 'exit' to leave MinGW shell and restore Cygwin environment." /usr/bin/bash --rcfile ~/.mingwrc I recommend having at least this in the ~/.mingwrc file: alias make=mingw32-make PS1='MinGW: \W \$ ' The prompt change reminds you that you are in a sub-shell set up for MinGW. The alias for 'make' ensures you don't accidentally run Cygwin's make, which won't work with Makefile.mingw. We could just leave /c/cygwin/bin out of the environment, but there are Cygwin tools we want access to, like vim. As long as all the MinGW ones override those Cygwin also provides, we don't need to worry about having both in the PATH. Besides, having the alias is nice for those who have 'make' committed to muscle memory. Building on Linux ~~~~~~~~~~~~~~~~~ You might wish to build MySQL++ with MinGW because you're not actually running Windows, but need Windows executables. The thought being that this lets you use GCC, the same compiler you're probably using to make native executables. There are indeed ways to make this work. The most "native" way to do this is to run MinGW under Wine. Leonti Bielski provided these instructions: 1. Install MinGW through Wine: $ wine MinGW-5.1.6.exe 2. Add the MinGW directory to Wine's PATH with Wine regedit: http://winehq.org/site/docs/wineusr-guide/environment-variables 3. Install MySQL under Wine, or at least unpack the Windows ZIP file version of MySQL in a place where Wine can find it. You don't need to run a Windows MySQL server under Wine. We're only doing this to get the MySQL C API library and its headers, which MySQL++ builds against. The resulting MinGW build of MySQL++ can talk to a native MySQL server out in Wine's host environment or on some other machine. 4. Modify Makefile.mingw to match the install location for the MySQL C API files. 5. Build MySQL++ with: $ wine mingw32-make -f Makefile.mingw Another way is to build a Windows virtual machine, such as with VMware or VirtualBox. In that case, you'd use the regular build instructions at the top of this document. You might think to avoid the need for Wine or Windows by use of a MinGW cross-compiler: $ ./configure --target=mingw32 $ make Unfortunately, that currently doesn't work. The reason is that our autoconf build system assumes a typical POSIX type target, which MinGW is not. We made this assumption because we have a perfectly good MinGW build option, Makefile.mingw. But, that also won't work on a POSIX system because that Makefile assumes external commands run under cmd.exe, not some Unixy shell. Thus the advice to build with Makefile.mingw under Windows or something sufficiently close to it. If you really wanted to, you could extend the autoconf build system to make it realize when it's being used to cross-compile for MinGW. Patches thoughtfully considered; see HACKERS.txt. |
Added README-Solaris.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | For the most part, Solaris is just another Unix variant as far as MySQL++ is concerned. See README-Unix.txt for most of what you need to know to build and use MySQL++. Prerequisite: Install the MySQL Development Files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MySQL++ is built on top of the MySQL C API library, so it needs the C API development files to build against. With the current version of Solaris, at least, a MySQL package is included on the operating system disk, but not installed by default. To install it, oull down the GNOME System menu, go to Administration, and then to Package Manager. Search for "mysql5" and install those packages. While there, you may also need to install the gcc packages, if you haven't done that already. I'm not sure, but you may need to install Perl as well. Don't search for just "mysql" in Package Manager, as that will also bring up legacy MySQL 4.0 packages. MySQL++ may build against 4.0 still; it's been a while since we've tested it. What is certain is that the examples won't run against 4.0 without modification, as they assume the availability of UTF-8 character set support, which was added in 4.1. It's no doubt possible to use the official binaries from mysql.com instead, or to build from source. We don't do that ourselves, though, and don't have reports from those who have, so we can't advise on how to do it. C API Development File Directories ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sun's MySQL package installs the development files in relatively uncommon locations. The libraries are in /usr/mysql/lib/mysql, and the headers are in /usr/mysql/include/mysql. Way to be redundant, guys. :) |
Added README-Unix.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | Platform Variations ~~~~~~~~~~~~~~~~~~~ This file only covers details common to all Unix variants supported by MySQL++. For platform-specific details, see the file appropriate to your OS: README-Cygwin.txt README-Linux.txt README-Mac-OS-X.txt README-Solaris.txt There are no special instructions for any other Unix flavors. Building the Library and Example Programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MySQL++ uses GNU autoconf, so you can build it with the standard commands: $ ./configure $ make $ su # make install 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 doesn't work, it's because the library and header files aren't in typical locations under the directory you gave for configure to find them. So, you need to specify them separately with --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. --with-field-limit: This lets you increase the maximum field limit for template queries and SSQLSes. By default, both are limited to 25 fields. See chapter 8.2 in the user manual for details: http://tangentsoft.net/mysql++/doc/html/userman/configuration.html --enable-thread-check: Builds MySQL++ with threading 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. Note that this is a suggestion, not a command. If we can't figure out the system's threading model or can't find the thread-aware build of the C API library, configure won't fail. It just reverts to the standard single-thread build. See the chapter on threading in the user manual for more details and advice on creating thread-safe programs with MySQL++. Building a Static Library ~~~~~~~~~~~~~~~~~~~~~~~~~ As shipped, MySQL++ only builds a shared library. It's possible to change things so you get a static library instead. Before we get to "how," beware that liking statically to MySQL++ has legal consequences that may matter to you, due to the library's license, the GNU LGPL. Familiarize yourself with the license, and consider getting legal counsel before proceeding. Also, see the MySQL++ FAQ: http://tangentsoft.net/mysql++/#faq There is more on this topic there. The necessary changes are all in mysql++.bkl: - Change the <dll> tag to <lib>. (Remember the closing tag!) - Remove the <dllname> tag - Remove the <so_version> tag Then, re-bootstrap the library. See HACKERS.txt if you need further instruction on doing that. |
Added README-Visual-C++.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | Prerequisites ~~~~~~~~~~~~~ You need to have the MySQL C API development files on your system, since MySQL++ is built on top of it. The easiest way to get it is to download Connector/C from mysql.com. If you need the MySQL server on your development system anyway, you you can choose to install the development files along with the server. Some versions of the MySQL Server installer for Windows have installed the development files by default, while others have made it an optional install. Project Files ~~~~~~~~~~~~~ The distribution comes with three sets of .sln and .vcproj files in the vc2003, vc2005 and vc2008 subdirectories. We do this for several reasons: 1. It lets you build MySQL++ with multiple versions of Visual C++ without the build products conflicting. 2. For Visual C++ 2003, we had to disable the SSQLS feature because changes made in MySQL++ 3.0 now cause the compiler to crash while building. See the Breakages chapter in the user manual for workarounds if you must still use VC++ 2003. 3. The VC++ 2008 project files get built for 64-bit output, while the other two build 32-bit executables. With VC++ 2003, we have no choice about this, since it only supports 32-bit targets. VC++ 2005 did have experimental 64-bit compilers available, but their beta nature was only one reason we chose not to use them. The real reason is that the current MySQL++ build system isn't currently set up to make it easy to build both 32- and 64-bit libraries and executables at the same time within the same solution. Bakefile allows it, but it would require forking many of the build rules in mysql++.bkl so we can do things like have separate MYSQL_WIN_DIR values for each bitness. (See below for more on this variable.) For that same reason, the VC++ 2008 project files are set up to build 64-bit libraries and executables *only*. It is possible to upgrade these project files to work with newer versions of Visual C++, but beware that the upgrade feature tends to be problematic. If you want to do a 32-bit build on VC++ 2008 or newer, it is easiest to open the vc2005\* project files and let Visual Studio upgrade them for you. The alternative, starting with the vc2008 files, requires that you add a 32-bit build option to all of the many targets in MySQL++, then optionally delete the 64-bit targets. This is a lot more work. Plus, it only works if you have the 64-bit compilers installed, since Visual Studio will refuse to open project files where all targets must be built with compilers that aren't installed, even if your goal is to immediately adjust them to use compilers that *are* installed. When converting the VC++ 2008 project files to VC++ 2012, Visual Studio will change the output directories from Debug to Debug\x64 (and similar for Release), but it won't also change the link paths from Debug to Debug\x64, so that the library and examples will compile but not link. The migration tool detects that there is a problem, but it can't fix its own mess. You have to manually fix it. There were also problems in VC++ 2010 when you had converted 32-bit VC++ 2008 projects and then were trying to switch them to 64-bit. It ended up being simpler in this case to just start over from scratch and build your own project files. Using Nonstandard MySQL Installations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Visual Studio project files that come with MySQL++ have everything set up correctly for the common case. The biggest assumption in the settings is that you're building against the current stable version of Connector/C, which gets installed here at the time of this writing: C:\Program Files\MySQL\MySQL Connector C 6.1\ If you installed a different version, or it's in a different directory, or you've installed the development files as part of MySQL Server on the same machine, you need to change the project files to reference the C API development files in that other location. There are two ways to do this. The hard way is to make 16 different changes each to 44 separate project files. If you're a talented Visual Studio driver, you can do this in as little as about 5 or 6 steps. You might even get it right the first time. If you are not so talented, you have to make all ~700 changes one at a time, and you almost certainly will *not* get it right the first time. The somewhat easier way is to open all these files in a text editor that lets you make a global search and replace on all open files. The easy way is to install Bakefile (http://bakefile.org/), change the value of the MYSQL_WIN_DIR variable near the top of mysql++.bkl in the top level of the MySQL++ source tree, and run rebake.bat. This will rebuild all of the project files for you, using the new MySQL path in all the many places it's needed. Building the Library and Example Programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You must build both the Debug and Release versions of the library, because a release build of your program won't work with a Debug version of the MySQL++ DLL. These DLLs get different names, so you can install them in the same directory if needed: mysqlpp_d.dll for the Debug version, and mysqlpp.dll for the Release version. With the library built, run at least the resetdb and simple1 examples to ensure that the library is working correctly. In addition to the other generic examples, there are a few Visual C++ specific examples that you might want to look at in examples\vstudio. See README-examples.txt for further details. Once you're sure the library is working correctly, you can run the install.hta file at the project root to install the library files and headers in a directory of your choosing. (Aside: You may not have come across the .hta extension before. It's for a rarely-used feature of Microsoft's Internet Explorer, called HTML Applications. Know what Adobe AIR is? Kinda like that, only without the compilation into a single binary blob which you must install before you can run it. Just open install.hta in a text editor to see how it works.) Using MySQL++ in Your Own Projects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is covered in the user manual, chapter 9. Working With Bakefile ~~~~~~~~~~~~~~~~~~~~~ MySQL++'s top-level Visual Studio project files aren't maintained directly. Instead, we use a tool called Bakefile (http://bakefile.org/) to generate them from mysql++.bkl. Since there are so many project files in MySQL++, it's often simpler to edit this source file and "re-bake" the project files from it than to make your changes in Visual Studio. To do this, download the native Windows version of Bakefile from the web site given above. Install it, and then put the installation directory in your Windows PATH. Then, open up a command window, cd into the MySQL++ directory, and type "rebake". This will run rebake.bat, which rebuilds the Visual Studio project files from mysql++.bkl. There's more information about using Bakefile in HACKERS.txt. 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++. |
Added README-examples.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | 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 [-s server_addr] [-u user] [-p password] On Windows, that would instead be: C:\mysql++\> exrun.bat resetdb [-s server] [-u user] [-p pass] You don't have to give any of these options. If you don't pass -s, it assumes the database server is running on the same machine, and so tries to contact the server over some form of local IPC. If you don't pass -u, it uses your own user name when logging into to the database server. If you don't pass -p, it assumes the database user has an empty password, which hopefully is not true. The -s option accepts many different forms of address. The main one is some sort of TCP/IP address, with an optional port number or service name. On Unixy systems, you can give a Unix domain socket name. On Windows, you can give just a period to use named pipes, if the server supports it. All of these are legal: . localhost 172.20.0.252:12345 /var/run/mysqld.sock my.server.name.com:mysql If you give -s but don't give a port number or service name with it, it assumes the default, 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. ssqls1-5: These demonstrate the SSQLS features. Read the SSQLS sections in the user manual for details about these examples. 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. tquery1-3: Shows how to use the template query facility. transaction: Shows how to use the Transaction class to create transaction sets which automatically roll back if not explicitly committed. deadlock: Shows how to handle errors that happen when the database server detects a deadlock in a transaction set. Also demonstrates the need for BadQuery::errnum() 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 way to express rules for selecting records in C++, to be used when SQL's WHERE clause isn't powerful enough. 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. cpoolp, cpoolw: Respectively, the POSIX and Windows threads variants of the ConnectionPool class demonstration. 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 anything given on the command line that isn't a switch to be a JPEG file name. We've included examples/logo.jpg as a sample, if you want to use that. fieldinf: 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 some of the data it's managing. 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 GUI examples, too: examples\vstudio\mfc.vcproj: MFC-based replacement for the simple2 example. examples\vstudio\wforms.vcproj: The same thing, only written in C++/CLI and using Windows Forms. Please follow the instructions in README-Visual-C++.txt before trying to build and run this example. The MySQL++ library build settings must be modified and the library rebuilt first. Although these examples show use of MySQL++ in a GUI rather than command line program, that's not the main point of these examples. What we're really showing here is how to deal with Unicode. The MySQL server prefers the UTF-8 encoding for Unicode, which works naturally with most non-Windows systems. Windows, on the other hand, uses a different Unicode character encoding, UCS-2. These examples show how to do the necessary conversions. (See the Unicode chapter in the user manual for more on this topic.) We need two different examples because Unicode conversions and string handling are so wildly different under .NET than with the native Win32 API. .NET makes these tasks much easier. These examples build and run as-is under Visual C++ 2005. To make them work with VC++ 2008, you will have to change several paths in both project's settings to reference the "vc2008" subdirectory instead of "vc2005": o Configuration Properties > Debugging > Working Directory o Configuration Properties > Linker > General > Additional Library Directories If you want to backport these examples to VC++ 2003, it's probably not hard. The main difficulty is that VS 2003 supports Managed C++, which isn't the same thing as C++/CLI. 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.bc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted README.cygwin.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted README.mingw.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added README.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 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 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. Its home page is http://tangentsoft.net/mysql++/ Prerequisites ~~~~~~~~~~~~~ To build MySQL++, you must have the MySQL C API development files installed. On Unixy systems (Linux, Mac OS X, Cygwin, *BSD, Solaris...), 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". If you're building on Windows with Visual C++ or MinGW, you need to install the native Win32 port of MySQL from mysql.com. 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. Additional Things to Read ~~~~~~~~~~~~~~~~~~~~~~~~~ Each major platform we support has a dedicated README-*.txt file for it containing information specific to that platform. Please read it. For authorship information, see the CREDITS.txt file. For license information, see the COPYING.txt file. If you want to change MySQL++, see the HACKERS.txt file. You should have received a user manual and a reference manual with MySQL++. If not, you can read a recent version online: http://tangentsoft.net/mysql++/doc/ Search the MySQL++ mailing list archives if you have more questions: http://lists.mysql.com/plusplus/ Building the Library ~~~~~~~~~~~~~~~~~~~~ MySQL++ uses Bakefile (http://bakefile.org/) to generate platform-specific project files and makefiles from a single set of input files. We currently support these build systems: autoconf: For Unixy platforms, including Linux, Mac OS X, and Cygwin, in addition to the "real" Unices. See README-Unix.txt for general instructions. Supplementary platform-specific details are in README-Cygwin.txt, README-Linux.txt, README-Mac-OS-X.txt, and README-Solaris.txt. MinGW: We ship Makefile.mingw for MinGW. It currently only builds the static version of the library for technical reasons. This has licensing ramifications. See README-MinGW.txt for details. Visual C++: We ship Visual Studio 2003, 2005, and 2008 project files. No older version of Visual C++ will build MySQL++, due to compiler limitations. See README-Visual-C++.txt for more details. Xcode: We ship an Xcode v2 project file. It hasn't been tested much yet, since the autoconf method works just fine on OS X. As a result, we need both success and failure reports on the mailing list. See README-Mac-OS-X.txt for more information. Example Programs ~~~~~~~~~~~~~~~~ You may want to try out the programs in the examples subdirectory to ensure that the MySQL++ API and your MySQL database are both working properly. Also, these examples give many examples of the proper use of MySQL++. See README-examples.txt for further details. 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. 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. 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.txt file first for guidance. If you follow the advice in that file, your patch will be more likely to be accepted. If You Want to Hack on MySQL++... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you intend to change the library or example code, please read the HACKERS.txt file. If you want to change the user manual, read doc/userman/README.txt If you want to change the reference manual, see the Doxygen manual: http://www.stack.nl/~dimitri/doxygen/manual.html |
Deleted README.unix.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted README.vc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added RELEASE-CHECKLIST.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | - Change version number in configure.ac and mysql++.bkl. All other places the version number occurs are generated files created from one of these two. If there's a corresponding *.in file for the one you're looking at, the version number was substituted in by autoconf from configure.ac. Otherwise, the file was most likely created by the build system using the version number in mysql++.bkl. - Run "make abicheck". There should be no changes. You may have to run the following command in the current "stable" directory before this will succeed, since it depends on there being an ACC dump file in place already. $ abi-compliance-checker -lib mysqlpp -dump abi.xml ("Stable" is assumed to be in ../3.1.0 relative to the svn "head" checkout, as I write this.) This dependence on an existing ABI dump file is deemed reasonable since the ABI of the stable version had better not be changing! Plus, it saves some processing time, since ACC can load the stable ABI info without re-parsing its headers and library file. - Re-bootstrap the system in pedantic mode, then do a clean rebuild. Fix any new errors and warnings. Known bogus warnings: - Query's std::basic_ios<> base class is not being initialized. Yes, we know. We don't care. - The "==" float comparisons in lib/stadapter.cpp are harmless. They're comparisons against special NaN and infinity constants. Those are safe. - Re-bootstrap it again without "pedantic", to avoid shipping the pedantic build files. |
Changes to 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 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 | Patches for any of these thoughtfully considered! See the HACKERS.txt file for instructions on sending patches. Any Version ----------- o The DateTime family's time_t conversion operators should detect DATETIME("0") type values and return time_t(0) rather than attempt to stuff an out-of-range value into a smaller box. o Any time you must hand-roll some SQL code in your program, consider whether it could be generalized to a widely-useful API feature. o Suppress DOS line-ending related diffs from examples/cgi_jpeg output when running dtest on Windows. Check for -D? o Need to link statically to connect to MySQL Embedded? http://stackoverflow.com/questions/672451/ o When Bakefile allows, bring examples/vstudio/* into the top-level build system. This will let us generate separate project files for each VC++ version we support, let us use MYSQL_WIN_DIR variable instead of hard-coded paths, and build against the local version of MySQL++ instead of requiring it to be installed first. Should probably drop the MFC example project, to avoid requiring Visual C++ Professional. o Query::storein(slist<T>&) is unusable. As a template method, it must be defined in a header file; we cannot #include config.h from a header, thus the proper HAVE macro that would let us define this template method is never defined. One solution is to create lib/slist.h.in, parameterized by the detected slist type name and the header file defining it. This will #include the proper header file, define SList<T>::Type (a template typdedef: http://www.gotw.ca/gotw/079.htm), and #define MYSQLPP_HAVE_SLIST. Then Query::storein() can be wrapped by an ifdef checking for MYSQLPP_HAVE_SLIST, only defined when the configure script found a suitable slist type. Also create a default lib/slist.h file, checked into svn as lib/slistdef.h and copied to slist.h on tarball creation. Remove this file early in configure script run, so we're forced to overwrite its contents with detected values. Default version contains ifdefs for non-autoconf platforms where we know what slist definition is available on that platform. Xcode, for instance, will let us use <ext/slist>. o Add ctor and assignment operator that takes mysqlpp::null. You now have to call a 4-argument version of either the ctor or assign() to get a NULL SQL string. o The escape_q() functions aren't returning the right value when dealing with Null<T> wrapped types, such as sql_blob_null. o The current method SSQLS uses to compare floating point numbers is highly dubious. It just subtracts them, and checks that the absolute difference is under some threshold. The manual warns that this is fine for "human scale" applications, but even that's not actually true. It means that if Larry Ellison loses a hundredth of a penny in his couch, it is somehow significant. I have no idea how much money Larry Ellison is comfortable losing to his couch cushions, but it's probably closer to 1 ppm than the current threshold, which is 100 parts per quadrillion on the scale of $1 bn. For backards compatibility, we should keep this method, but we should add these two more mathematically sound methods: - Percentage: Divide the smaller number into the larger, then compare against a threshold. The default should be something like 1.000001 (1 ppm), which lets us make much finer distinctions without running out of precision, even with single-precision numbers counting Bill Gates' losses to his couch cushions. - Logarithmic, or "Bels": Same as percentage, but on a log10 scale so it works better for FP numbers, which are based on powers of 10. Logarithms are more costly than division, and we still need a division for this, so it shouldn't be the new default. 1 ppm is ~4.3e-7, which is below what single-precision FP can distinguish. Increasing the threshold to a value you *can* distinghish with a 32-bit IEEE float makes it ignore significant amounts of money in Carlos Slim's couch cusions. (Hundreds of dollars.) Therefore, we should use something like 1e-7 or 1e-8 anyway, and make it clear that the default threshold is only suitable for doubles. Someone using single precision FP should increase the threshold to 1e-5 or so. Such a person would be assumed to know what they're doing. It's probably more efficient to change the algorithm from: double diff = log10(a > b ? a / b : b / a); to: double diff = fabs(log10(a / b)); Logarithms give the same magnitude result for a/b as b/a, differing only in sign. fabs() is probably implemented as an intrinsic that just clears a single bit, which should be cheaper than a floating point comparison followed by a jump. With suitable tuning, this method would allow you to distinguish the change lost by a single Pentagon contractor's lobbyist to a single couch, on a single occasion, as compared to the combined net worth of all Pentagon contractors and their employees, assigns, mistresses, and, ah, hired help. If you use doubles, anyway. v3.3 Plan: Finish SSQLS v2 -------------------------- See http://lists.mysql.com/plusplus/6929 for high-level plan. o Goal: Restore VC++ 2003 compatibility with SSQLS, lost with v1 o C++ code generator, from walking DSL parse tree: examples/stock.ssqls gives ssqls_stock.h containing: class SQLStock : public mysqlpp::SsqlsBase { public: SQLStock(Connection* conn = 0); // default ctor SQLStock(const SQLStock& other); SQLStock(const mysqlpp::Row& row, Connection* conn = 0); // full init from query SQLStock(mysqlpp::sql_bigint key1); // exemplar creation SQLStock(Connection* conn, mysqlpp::sql_bigint key1) // calls load(); SQLStock( mysqlpp::sql_bigint f1, mysqlpp::sql_bigint f2, mysqlpp::sql_double f3, mysqlpp::sql_double f4, const mysqlpp::sql_date& f5, const mysqlpp::sql_mediumtext& f6); // full init SQLStock(Connection* conn, mysqlpp::sql_bigint f2, mysqlpp::sql_double f3, mysqlpp::sql_double f4, const mysqlpp::sql_date& f5, const mysqlpp::sql_mediumtext& f6); // calls create() SQLStock(Connection* conn, mysqlpp::sql_bigint f1, mysqlpp::sql_bigint f2, mysqlpp::sql_double f3, mysqlpp::sql_double f4, const mysqlpp::sql_date& f5, const mysqlpp::sql_mediumtext& f6); // calls save() bool createTable(Connection* conn = 0) const; const char* getTableName() const { return class_table_name_ || table(); } void setTableName(const char* name) { instance_table(name); } static void setTableName(const char* name) { class_table_name_ = name; } std::ostream& equal_list(std::ostream& os) const; std::ostream& json(std::ostream& os) const; std::ostream& name_list(std::ostream& os) const; std::ostream& value_list(std::ostream& os) const; std::ostream& xml(std::ostream& os) const; mysqlpp::sql_bigint getId() const; mysqlpp::sql_bigint getNum() const; mysqlpp::sql_double getWeight() const; mysqlpp::sql_double getPrice() const; const mysqlpp::sql_date& getSdate() const; const mysqlpp::sql_mediumtext& getDescription() const; void setId(mysqlpp::sql_bigint value); void setNum(mysqlpp::sql_bigint value); void setWeight(mysqlpp::sql_double value); void setPrice(mysqlpp::sql_double value); void setSdate(const mysqlpp::sql_date& value); void setDescripion(const mysqlpp::sql_mediumtext& value); bool operator<(const SQLStock& rhs) const; SQLStock& operator=(const SQLStock& rhs); protected: mysqlpp::sql_bigint id_; mysqlpp::sql_bigint num_; mysqlpp::sql_double weight_; mysqlpp::sql_double price_; mysqlpp::sql_date sdate_; mysqlpp::sql_mediumtext description_; std::bitset<6> set_fields_; private: static const char* class_table_name_; }; ...and ssqls_stock.cc, containing implementation for same. o Ensure we're using case-insensitive SQL column to C++ field name matching. Column names aren't case-sensitive in SQL. o SQL table updater/builder, -T option, taking .ssqls and creating or updating the DB table to match. o If using accessors, generate "std::bitset<num_fields> is_set_", and set the appropriate bit when calling each setFoo() so we can intuit which fields were set. Probably also need an enum: enum FieldIndices { id_field_index_, num_field_index_, ... }; This will allow Query::select(), for instance, to figure out that we want it to select by a non-key field, returning all matches. o Define operator<< for SSQLS and a set of manipulators which govern whether the operator calls equal_list(), json(), name_list(), value_list(), or xml() to do the actual insertion. o Define operator<< for sequence_container<SsqlsBase> and similar for associative containers. Give mysql(1)-like ASCII grid or some other table format. o Define operator>> for SSQLS, taking XML as input, in the form emitted via xml(). expat uses the new BSD license, so maybe we can just drop it in the tree, with an option to use the platform expat on autoconf systems. o MySQL table metadata to SSQLSv2 data structure translator. (-s, -u, -p and -t flag support.) Add this to dtest, extracting stock.ssqls definition from DB. o Replace Query's template methods taking SSQLSes with concrete methods taking const SsqlsBase&. o Create Query::remove(const SsqlsBase&) o Try to remove of 'explicit' from Date, DateTime and Time ctors taking stringish types. (Can't do it for real until v4, but we can lay the ground work here.) o Auto-create() ctor: if there is an auto_increment field, populate it on query success. o Detect ctor conflicts corresponding to sql_create_N(N, N...) in SSQLSv1. ssqlsxlat can be smart enough to just not emit duplicate ctors. o Special case of ctor suppression: if the number of key fields equals the total number of fields, you get an auto-load() ctor, not auto-update(). o Replace CREATE TABLE SQL in resetdb with create_table() calls. o Option to use integer indices into Row when populating? Only bother if it gives a speed advantage we can actually see, because it removes all the dynamic typing advantages we got with the change to field name indices in v3.0. o Try to add Query::storein(container, ssqls), which generates SELECT * from {ssqls.table()} and stores the result. May not be possible due to existing overloads, but try. If it works, use this form in the userman Overview section, saving one LOC. o Convert SSQLS v1 examples to v2. SSQLS v2 isn't done until there's a straightformward conversion path for all examples. o Add #warning to generated ssqls.h saying that you should now use SSQLS v2. Wrap it in a check for MYSQLPP_ALLOW_SSQLS_V1, so people can disable the warning. v3.4 Tentative Plan ------------------- o Add Query::storein<Container, T>(container), getting table name from container::value_type.table() instead. o Define operator<< for Fields, Row, StoreQueryResult, etc., giving CSV format. o Remove libexcommon. Between above and SSQLSv2, we should have everything we need to get equivalent output without special purpose code. There should be no ad hoc data dumping code in the examples. o Bring back mandatory quoting for manipulators? If someone says os << mysqlpp::escape << foo; do they not really really mean escape foo? Automatic quoting and escaping is different. See http://lists.mysql.com/plusplus/7999 o Configure script should try to get MySQL C API directories from mysql_config. o If pkg-config is available, register ourselves with it using information discovered by configure. Also, write out a mysql++-config script, which either wraps pkg-config or reinvents it, poorly, for systems that don't have it. o Add String::operator==(const mysqlpp::null_type&). Needed to allow comparison of row[x] returns to SQL null. Change one of the examples to show it? o Memory "leak" and C API library init fixes: - Add DBDriver::library_begin() and library_end(), wrapping similarly named functions in the C API. - Create Process class, which you create at the top of main() on the stack, purely to call these automatically. - Update userman to recommend creating Process object in ConnectionPool derivatives, instead. - Create Thread class to call existing DBDriver::thread_start() and thread_end(), similar to Process, created on the stack of the thread entry function. - Move memory leak FAQ into userman, rewriting it to cover all this. o mysqlpp::execute manipulator. Immediately executes built query string. Works best with exceptions, as that's the only way to detect failures. o Chris Frey's packarray class 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 Create a backtick manipulator for use by field_list() in row.h and ssqls.h. These currently use do_nothing0, but that prevents use of SQL reserved words as identifiers. o Has experience with new thread awareness changed our mind on atomic inc/dec of reference counts in RefCounted*? o Create a fixed-point data type for use with SQL's DECIMAL and related types. Right now, sql_decimal is a typedef for double, so you lose accuracy in the fractional part. Don't forget to include an "is_null" flag to cope with conversion from infinite or NaN float values; that's how MySQL stores these. o Optional checked conversions in String for numerics: throw BadConversion on range overflow? o Add Query::storein_if(), mirroring store_if() o Add a method to mysqlpp::String to return a widened version of the string. Probably make return type templatized so we can return wstring, C++/CLI native strings, etc. Then convert examples that do this conversion to use this new mechanism. o Try to add operator std::string to String. If it doesn't work, explain why not in the userman, and in Row::operator[] refman. o Wrap LOAD DATA INFILE: bool Query::load_file( const char* path, bool local_path, const char* table, const char* field_terminator = 0, // default \t const char* field_encloser = 0, // default none const char* field_escape = 0, // default \ const char* line_terminator = 0, // \n on *ix, \r\n on Windows const char* line_starter = 0, // default none const char* character_set = 0, // default UTF-8 const char* comment_prefix = 0, // ignore no lines bool replace_existing = false, bool ignore_duplicates = false, bool low_priority = false, int skip_lines = 0); o Wrappers for above: load_local_tab_file(), load_local_csv_file(), load_remote_*()... o Query::save_file() interfaces, wrapping SELECT ... INTO FILE, modeled on above. v4.0 or Later ------------- o Database independence: - Use libdbi or similar? http://libdbi.sf.net/ - Make DBDriver class purely abstract; move its entire functional contents to new MysqlDriver. - Must create at least two other DBDriver subclasses to ensure base class is reusable before releasing v4.0. PostgresDriver and SqlLiteDriver? - Templatize all classes that use DBDriver interface with the DB driver type. This lets you specify the driver type to use with a Connection and all its children without modifying the existing method parameter lists. This also lets us worry less about C API types, as they can be hidden away behind typedefs: class MysqlDriver : public DBDriver { ... typedef MYSQL_ROW row_type; ... } template <class DBD = MysqlDriver> class Connection ... { ... Query<DBD> query(); ... } template <class DBD = MysqlDriver> class UseQueryResult { ... DBD::row_type fetch_raw_row(); } - Tricky bits: - Initializing result set objects. - type_info module. Extremely closely tied to MySQL C API right now. Will probably have to turn it into a parallel class hierarchy to DBDriver, or fold it in with same. - Building MySQL++ on systems without autoconf. How to specify what DB engines are available? Probably default to supporting MySQL only, and let people turn things on manually as they need them. Or, maybe make them use Bakefile so they can fiddle with the options if they want something atypical. o Fork mysqlpp::String into mysqlpp::Blob, which differs only in that it knows that it should be automatically quoted and escaped when inserted into a SQL query. Could do this in 3.x, but it's a pretty serious API breakage. o Some sort of support for prepared statements. Can we hijack the template query mechanism? o If SSQLSv2 does use a common base class, change Query template methods taking SSQLS into concrete methods taking SsqlsBase&. o Make Query::insert(), replace() and update() execute their queries immediately. Requires an ABI break, because they'll have to return SimpleResult. o Switch Query's safe bool to overload basic_ios<>::operator void*() instead. We create an ambiguous conversion in bool context with some C++ standard libraries otherwise. o Templatize mysqlpp::String on value_type so it can be used to hold wide characters. Then the method that converts UTF-8 to the platform's best wide character type can just return a different variant of mysqlpp::String. o Add wrapper functions to Null<> like length() that call the corresponding function on data member, if present, to make it more transparent. At minimum, mirror the std::string API. o Transaction class should check an "in transaction" flag on Connection (or DBDriver) before sending BEGIN, defaulting to false. If set, the Transaction object does nothing. If not set, set it and send the query. This prevents it from trying to set up nested queries, which MySQL doesn't support. o Remove throw-spec for std::out_of_range from SQLTypeAdapter::at(). It no longer throws this, and throw-specs are passee' anyway. o Store failed query string in BadQuery exception object, to make logging and debugging easier. One could have a try block wrapping many queries, and be able to recover the failed query string from the exception object, instead of somehow keeping track yourself. Patch: http://lists.mysql.com/plusplus/8374 o Query and SQLStream could have a common base class that would allow the stream manipulator functions to catch and modify strings based on only one dynamic_cast instead of requiring two as it does since the addition of the SQLStream class. o Make internal call chain steps like Query::execute(SQLQueryParms&) protected? No good reason for end users to call it, and making it part of the public API causes people to try calling it, and discovering that it's not a very elegant interface, compared to the ones taking SQLStrings. o SQL time type allows +/- 839 hours of range. v3.0 code doesn't cope with negative times, and if we change it to use signed integers, we'll still only get +/-127 hours instead of +255. Need to switch the hour field to a short to get the full range. o Create a thread-safe message queue for separating DB access and data use into multiple threads. Something like ConnectionPool, optional and with no ties to the internals of MySQL++. There could be an adapter between one end of the queue and a Connection object, which creates Queries to handle standardized messages, delivering the results back to the queue. o Get rid of two-step create in DBDriver, requiring a connection to be established in ctor for object to be valid? RAII. The DB-specific functions that don't require a connection can be static methods. Tricky bit: a failed Connection::connect() call will likely be followed by an indirect call to DBDriver::err*(). Does Connection cache the error value and message? If we can pull this off, we can drop the DBDriver::is_connected_ flag and change Connection::connected() to "return driver_ != 0". o Add STL-like custom Allocator template parameters to memory-hungry classes like Row? Useful in apps that process lots of data over long periods, causing heap fragmentation with the default C++ allocator. o Audit library for non-virtual methods that could be profitably made virtual. Many are non-overridable now purely because changing them would break the ABI, so now's the time to fix that. |
Added abi.xml.in.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | <version> @MYSQLPP_VERSION_MAJOR@.@MYSQLPP_VERSION_MINOR@.@MYSQLPP_VERSION_BUGFIX@ </version> <headers> lib </headers> <libs> . </libs> |
Added bk-deps.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #!/bin/sh # This script is part of Bakefile (http://www.bakefile.org) autoconf # script. It is used to track C/C++ files dependencies in portable way. # # Permission is given to use this file in any way. DEPSMODE=gcc DEPSFLAG="-MMD" DEPSDIRBASE=.deps if test $DEPSMODE = gcc ; then $* ${DEPSFLAG} status=$? # determine location of created files: while test $# -gt 0; do case "$1" in -o ) shift objfile=$1 ;; -* ) ;; * ) srcfile=$1 ;; esac shift done objfilebase=`basename $objfile` builddir=`dirname $objfile` depfile=`basename $srcfile | sed -e 's/\..*$/.d/g'` depobjname=`echo $depfile |sed -e 's/\.d/.o/g'` depsdir=$builddir/$DEPSDIRBASE mkdir -p $depsdir # if the compiler failed, we're done: if test ${status} != 0 ; then rm -f $depfile exit ${status} fi # move created file to the location we want it in: if test -f $depfile ; then sed -e "s,$depobjname:,$objfile:,g" $depfile >${depsdir}/${objfilebase}.d rm -f $depfile else # "g++ -MMD -o fooobj.o foosrc.cpp" produces fooobj.d depfile=`echo "$objfile" | sed -e 's/\..*$/.d/g'` if test ! -f $depfile ; then # "cxx -MD -o fooobj.o foosrc.cpp" creates fooobj.o.d (Compaq C++) depfile="$objfile.d" fi if test -f $depfile ; then sed -e "\,^$objfile,!s,$depobjname:,$objfile:,g" $depfile >${depsdir}/${objfilebase}.d rm -f $depfile fi fi exit 0 elif test $DEPSMODE = mwcc ; then $* || exit $? # Run mwcc again with -MM and redirect into the dep file we want # NOTE: We can't use shift here because we need $* to be valid prevarg= for arg in $* ; do if test "$prevarg" = "-o"; then objfile=$arg else case "$arg" in -* ) ;; * ) srcfile=$arg ;; esac fi prevarg="$arg" done objfilebase=`basename $objfile` builddir=`dirname $objfile` depsdir=$builddir/$DEPSDIRBASE mkdir -p $depsdir $* $DEPSFLAG >${depsdir}/${objfilebase}.d exit 0 elif test $DEPSMODE = unixcc; then $* || exit $? # Run compiler again with deps flag and redirect into the dep file. # It doesn't work if the '-o FILE' option is used, but without it the # dependency file will contain the wrong name for the object. So it is # removed from the command line, and the dep file is fixed with sed. cmd="" while test $# -gt 0; do case "$1" in -o ) shift objfile=$1 ;; * ) eval arg$#=\$1 cmd="$cmd \$arg$#" ;; esac shift done objfilebase=`basename $objfile` builddir=`dirname $objfile` depsdir=$builddir/$DEPSDIRBASE mkdir -p $depsdir eval "$cmd $DEPSFLAG" | sed "s|.*:|$objfile:|" >${depsdir}/${objfilebase}.d exit 0 else $* exit $? fi |
Added bmark.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | All unit tests passed ---------------- BEGIN resetdb OUTPUT ---------------- Connecting to database server... Dropping existing sample data tables... Creating stock table... Populating stock table...inserted 4 rows. Creating empty images table... Creating deadlock testing tables... Reinitialized sample database successfully. ================ END resetdb OUTPUT ================ ---------------- BEGIN simple1 OUTPUT ---------------- We have: Nürnberger Brats Pickle Relish Hot Mustard Hotdog Buns ================ END simple1 OUTPUT ================ ---------------- BEGIN simple2 OUTPUT ---------------- Item Num Weight Price Date Nürnberger Brats 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.10 1998-04-23 ================ END simple2 OUTPUT ================ ---------------- BEGIN simple3 OUTPUT ---------------- Item Num Weight Price Date Nürnberger Brats 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.10 1998-04-23 ================ END simple3 OUTPUT ================ ---------------- BEGIN store_if OUTPUT ---------------- Records found: 2 Item Num Weight Price Date Nürnberger Brats 97 1.5 8.79 2005-03-10 Hot Mustard 73 0.95 0.97 1998-05-25 ================ END store_if OUTPUT ================ ---------------- BEGIN for_each OUTPUT ---------------- There are 322 items weighing 416.85 stone and costing 1147.19 cowrie shells. ================ END for_each OUTPUT ================ ---------------- BEGIN multiquery OUTPUT ---------------- Multi-query: DROP TABLE IF EXISTS test_table; CREATE TABLE test_table(id INT); INSERT INTO test_table VALUES(10); UPDATE test_table SET id=20 WHERE id=10; SELECT * FROM test_table; DROP TABLE test_table Result set 0 is empty. Result set 1 is empty. Result set 2 is empty. Result set 3 is empty. Result set 4 has 1 row: +----+ | id | +----+ | 20 | +----+ Result set 5 is empty. Stored procedure query: DROP PROCEDURE IF EXISTS get_stock; CREATE PROCEDURE get_stock( i_item varchar(20) ) BEGIN SET i_item = concat('%', i_item, '%'); SELECT * FROM stock WHERE lower(item) like lower(i_item); END; Result set 0 is empty. Result set 1 is empty. Query: CALL get_stock('relish') Result set 0 has 1 row: +---------------+-----+--------+-------+------------+-------------+ | item | num | weight | price | sdate | description | +---------------+-----+--------+-------+------------+-------------+ | Pickle Relish | 87 | 1.5 | 1.75 | 1998-09-04 | NULL | +---------------+-----+--------+-------+------------+-------------+ Result set 1 is empty. ================ END multiquery OUTPUT ================ ---------------- BEGIN tquery1 OUTPUT ---------------- Query: select * from stock Records found: 4 Item Num Weight Price Date Nuerenberger Bratwurst 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.1 1998-04-23 ================ END tquery1 OUTPUT ================ ---------------- BEGIN resetdb OUTPUT ---------------- Connecting to database server... Dropping existing sample data tables... Creating stock table... Populating stock table...inserted 4 rows. Creating empty images table... Creating deadlock testing tables... Reinitialized sample database successfully. ================ END resetdb OUTPUT ================ ---------------- BEGIN tquery2 OUTPUT ---------------- Query: select * from stock Records found: 4 Item Num Weight Price Date Nuerenberger Bratwurst 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.1 1998-04-23 ================ END tquery2 OUTPUT ================ ---------------- BEGIN tquery3 OUTPUT ---------------- Stuff we have a lot of in stock: Nuerenberger Bratwurst Pickle Relish ================ END tquery3 OUTPUT ================ ---------------- BEGIN tquery4 OUTPUT ---------------- Query: update stock set num = 70 where num < 70 Query: select * from stock Records found: 4 Item Num Weight Price Date Nuerenberger Bratwurst 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 70 1.1 1.1 1998-04-23 Query: select * from stock where weight > 1.2 or description like '%Mustard%' Records found: 3 Item Num Weight Price Date Nuerenberger Bratwurst 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 ================ END tquery4 OUTPUT ================ ---------------- BEGIN resetdb OUTPUT ---------------- Connecting to database server... Dropping existing sample data tables... Creating stock table... Populating stock table...inserted 4 rows. Creating empty images table... Creating deadlock testing tables... Reinitialized sample database successfully. ================ END resetdb OUTPUT ================ ---------------- BEGIN ssqls1 OUTPUT ---------------- We have: Nürnberger Brats Pickle Relish Hot Mustard (good American yellow mustard, not that European stuff) Hotdog Buns ================ END ssqls1 OUTPUT ================ ---------------- BEGIN ssqls2 OUTPUT ---------------- Query: INSERT INTO `stock` (`item`,`num`,`weight`,`price`,`sDate`,`description`) VALUES ('Hot Dogs',100,1.5,NULL,'1998-09-25',NULL) Query: select * from stock Records found: 5 Item Num Weight Price Date Nürnberger Brats 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.1 1998-04-23 Hot Dogs 100 1.5 (NULL) 1998-09-25 ================ END ssqls2 OUTPUT ================ ---------------- BEGIN ssqls3 OUTPUT ---------------- Query: UPDATE `stock` SET `item` = 'Nuerenberger Bratwurst',`num` = 97,`weight` = 1.5,`price` = 8.7899999999999991,`sDate` = '2005-03-10',`description` = NULL WHERE `item` = 'Nürnberger Brats' Query: select * from stock Records found: 5 Item Num Weight Price Date Nuerenberger Bratwurst 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.1 1998-04-23 Hot Dogs 100 1.5 (NULL) 1998-09-25 ================ END ssqls3 OUTPUT ================ ---------------- BEGIN ssqls4 OUTPUT ---------------- Records found: 5 Item Num Weight Price Date Hot Dogs 100 1.5 (NULL) 1998-09-25 Hot Mustard 73 0.95 0.97 1998-05-25 Hotdog Buns 65 1.1 1.1 1998-04-23 Nuerenberger Bratwurst 97 1.5 8.79 2005-03-10 Pickle Relish 87 1.5 1.75 1998-09-04 Currently 65 hotdog buns in stock. ================ END ssqls4 OUTPUT ================ ---------------- BEGIN ssqls5 OUTPUT ---------------- Custom query: select * from stock where `weight` = 1.5 and `price` = 8.7899999999999991 ================ END ssqls5 OUTPUT ================ ---------------- BEGIN ssqls6 OUTPUT ---------------- Query: select * from stock Records found: 26 Item Num Weight Price Date Tiny Screws 1000 0.01 0.05 2008-11-11 Needle-nose Pliers 50 0.5 5.95 2008-11-12 Small Soldering Iron 40 0.5 15.95 2008-09-01 Large Soldering Iron 35 0.75 24.95 2008-08-01 Solder Wick 100 0.1 2.95 2008-04-01 Mini Screwdrivers, 3 pc. 30 0.4 8.95 2008-03-25 Mini Screwdrivers, 6 pc. 40 0.6 12.95 2008-04-01 Wire-wrapping Tool 25 0.2 4.95 2008-04-23 Red LED, 5mm, 3000mcd 300 0.01 0.29 2008-10-02 Orange LED, 5mm, 2500mcd 250 0.01 0.29 2008-07-31 Yellow LED, 5mm, 3000mcd 400 0.01 0.25 2008-09-30 Green LED, 5mm, 1000mcd 350 0.01 0.45 2008-09-27 Blue LED, 5mm, 3900mcd 500 0.01 0.34 2007-12-01 White LED, 5mm, 15000mcd 750 0.01 0.43 2008-02-01 AA Battery, single 220 0.05 0.5 2007-09-19 AA Battery, 4-pack 60 0.2 1.79 2007-08-03 AA Battery, 24-pack 8 1.2 9.99 2007-04-25 C Battery, single 100 0.075 0.65 2007-11-14 C Battery, 4-pack 25 0.3 2.29 2007-06-05 C Battery, 24-pack 5 1.8 10.99 2007-06-13 D Battery, single 180 0.08 0.7 2007-12-03 D Battery, 4-pack 45 0.3 2.59 2007-04-01 D Battery, 24-pack 12 1.9 11.99 2007-05-15 9-volt Battery, single 90 0.06 0.75 2008-01-02 9-volt Battery, 3-pack 17 0.2 1.99 2008-02-28 9-volt Batter, 20-pack 12 1.2 12.99 2007-12-28 ================ END ssqls6 OUTPUT ================ ---------------- BEGIN load_jpeg OUTPUT ---------------- Inserted "NULL" into images table, 0 bytes, ID 1 ================ END load_jpeg OUTPUT ================ ---------------- BEGIN cgi_jpeg OUTPUT ---------------- Content-type: text/plain No image content! ================ END cgi_jpeg OUTPUT ================ --- BEGIN ssqlsxlat -i examples/common.ssqls -o ERROR OUTPUT --- ==== END ssqlsxlat -i examples/common.ssqls -o ERROR OUTPUT ==== --- BEGIN ssqlsxlat -i examples/stock.ssqls -o ERROR OUTPUT --- ==== END ssqlsxlat -i examples/stock.ssqls -o ERROR OUTPUT ==== --- BEGIN ssqlsxlat -i test/test1.ssqls -o ERROR OUTPUT --- ==== END ssqlsxlat -i test/test1.ssqls -o ERROR OUTPUT ==== --- BEGIN ssqlsxlat -i test/test2.ssqls -o ERROR OUTPUT --- ==== END ssqlsxlat -i test/test2.ssqls -o ERROR OUTPUT ==== |
Changes to 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 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 | #!/bin/bash ARGS=1 BF_OPTIONS= MAINT_FLAGS="--cache-file=config.cache" while [ $ARGS != 0 ] do case "$1" in bat) cmd /c bootstrap.bat $BF_OPTIONS exit 0 ;; nodoc) BF_OPTIONS="-DBUILDDOCS=no $BF_OPTIONS" shift ;; noex) BF_OPTIONS="-DBUILDEXAMPLES=no $BF_OPTIONS" shift ;; nolib) BF_OPTIONS="-DBUILDLIBRARY=no $BF_OPTIONS" shift ;; nomaint) MAINT_FLAGS= shift ;; noopt) export CXXFLAGS="-g -O0" shift ;; pedantic) export CXXFLAGS="-g -O2 -ansi -pedantic -Wall -Wextra -W -Wold-style-cast -Wfloat-equal -Wwrite-strings -Wno-overloaded-virtual -Wno-long-long -Wno-variadic-macros -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC" shift ;; *) ARGS=0 ;; esac done # Check for existence of needed tools, so we can give a better error # message than the shell will. tools="make" # POSIX tools="$tools aclocal autoconf autoheader libtoolize" # autotools tools="$tools bakefile bakefilize bakefile_gen" # Bakefile for tool in $tools do if ! type -p $tool > /dev/null then echo "FAILED to find build tool '$tool'!" echo echo BOOTSTRAP FAILED! echo exit 1 fi done # Find location of Bakefile's stock M4 autoconf macros for d in /usr/share/aclocal /usr/local/share/aclocal \ '/c/Program Files (x86)/Bakefile/autoconf' do BAKEFILE_M4="$d" if [ -e "$BAKEFILE_M4/bakefile.m4" ] ; then break ; fi done if [ ! -e "$BAKEFILE_M4/bakefile.m4" ] then echo echo "Failed to find bakefile.m4. Add the directory containing" echo "this to the bootstrap script." echo exit 1 fi # Do Bakefile stuff first. Autoconf can't succeed without # autoconf_in.m4, which Bakefile creates. success= set -x && for d in 3 5 8 ; do mkdir -p vc200$d ; done && bakefilize && rm -f INSTALL && bakefile_gen $BF_OPTIONS && bakefile -f gnu -o Makefile.simple -DBUILDLIBRARY=no mysql++.bkl && set +x && success=shonuff # Do the autotools stuff if Bakefile steps succeeded if [ -n "$success" ] then rm -f config.cache mv autoconf_inc.m4 config > /dev/null 2>&1 # don't care if it fails set -x && aclocal -I config -I "$BAKEFILE_M4" && libtoolize && autoheader && autoconf && ./configure $MAINT_FLAGS $* && make lib/querydef.h lib/ssqls.h && set +x && success=awyeah fi # Detect failure in any part of above if [ -z "$success" ] then echo echo BOOTSTRAP FAILED! echo exit 1 fi |
Added bootstrap.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 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 | @echo off if not exist vc2003 mkdir vc2003 if not exist vc2005 mkdir vc2005 if not exist vc2008 mkdir vc2008 bakefile_gen %* if errorlevel 1 exit if not exist vc2003\mysql++.sln goto no_bakefile if not exist vc2005\mysql++.sln goto no_bakefile if not exist vc2008\mysql++.sln goto no_bakefile cd lib perl querydef.pl if errorlevel 1 exit if not exist querydef.h goto no_perl perl ssqls.pl if errorlevel 1 exit if not exist ssqls.h goto no_perl if not exist mysql++.h goto no_mysqlpp_h cd .. exit :no_bakefile echo. echo Bakefile doesn't seem to be installed on this system. Download it echo from http://bakefile.org/ You need version 0.2.3 or newer. echo. exit :no_perl echo. echo You need a Perl interpreter installed on your system, somewhere in echo the PATH. Any recent version or flavor should work; we don't use echo any special extensions. The easiest to install on Windows would be echo ActivePerl, from http://activestate.com/Products/activeperl/ echo If you're familiar with Unix, you might like Cygwin better instead: echo http://cygwin.com/setup.exe echo. cd .. exit :no_mysqlpp_h echo. echo WARNING: Can't make lib/mysql++.h echo. echo On Unixy systems, autoconf creates lib/mysql++.h from lib/mysql++.h.in echo but there is no easy way to do this on Windows. You can do it manually: echo just copy the file to the new name, and edit the MYSQLPP_HEADER_VERSION echo definition to put the proper version number parts into the macro. It echo needs to look something like this: echo. echo #define MYSQLPP_HEADER_VERSION MYSQLPP_VERSION(3, 0, 0) echo. echo It's important that the three numbers match the actual library version echo number, or else programs that check this (like resetdb) will fail. echo. echo Alternately, if you've also got MySQL++ installed on some Unixy type echo system, you can let its bootstrap procedure create mysql++.h and then echo copy it to the Windows machine. echo. cd .. |
Added cleanmf.
> > > | 1 2 3 | #!/bin/sh rm -f Makefile* rm -rf *.xcodeproj vc200? |
Deleted common.am.
|
| < < < < |
Changes to 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 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 | /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H /* Define if you have __gnu_cxx:slist container in <ext/slist> */ #undef HAVE_EXT_SLIST /* Define if you have ::slist container in <slist> */ #undef HAVE_GLOBAL_SLIST /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H /* Define if getopt() is available in libiberty.h */ #undef HAVE_LIBIBERTY_GETOPT /* Define to 1 if you have the `intl' library (-lintl). */ #undef HAVE_LIBINTL /* Define if you have the localtime_r() facility */ #undef HAVE_LOCALTIME_R /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H /* Define if your MySQL library has SSL functions */ #undef HAVE_MYSQL_SSL_SET /* Define if getopt() is available in unistd.h */ #undef HAVE_POSIX_GETOPT /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H /* Define if you have std::slist container in <slist> */ #undef HAVE_STD_SLIST /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the <synch.h> header file. */ #undef HAVE_SYNCH_H /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS |
Changes to 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 | # =========================================================================== # http://autoconf-archive.cryp.to/acx_pthread.html # =========================================================================== # # SYNOPSIS # # ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # LAST MODIFICATION # # 2008-04-12 # # COPYLEFT # # Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see <http://www.gnu.org/licenses/>. # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Macro Archive. When you make and # distribute a modified version of the Autoconf Macro, you may extend this # special exception to the GPL to apply to your modified version as well. AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no |
︙ | ︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # 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 | > | | | 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 | # 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) # ... -mt is also the pthreads flag for HP/aCC # 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 -pthreads/-mt/ # -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="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in |
︙ | ︙ | |||
183 184 185 186 187 188 189 | 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 | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | 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; return 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.]) |
︙ | ︙ | |||
207 208 209 210 211 212 213 | if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" | | > > > | > | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) |
︙ | ︙ |
Added config/autoconf_inc.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 | dnl ### begin block 00_header[./mysql++.bkl] ### dnl dnl This macro was generated by dnl Bakefile 0.2.9 (http://www.bakefile.org) dnl Do not modify, all changes will be overwritten! BAKEFILE_AUTOCONF_INC_M4_VERSION="0.2.9" dnl ### begin block 20_COND_BUILD_debug[./mysql++.bkl] ### COND_BUILD_debug="#" if test "x$BUILD" = "xdebug" ; then COND_BUILD_debug="" fi AC_SUBST(COND_BUILD_debug) dnl ### begin block 20_COND_BUILD_release[./mysql++.bkl] ### COND_BUILD_release="#" if test "x$BUILD" = "xrelease" ; then COND_BUILD_release="" fi AC_SUBST(COND_BUILD_release) dnl ### begin block 20_COND_DEPS_TRACKING_0[./mysql++.bkl] ### COND_DEPS_TRACKING_0="#" if test "x$DEPS_TRACKING" = "x0" ; then COND_DEPS_TRACKING_0="" fi AC_SUBST(COND_DEPS_TRACKING_0) dnl ### begin block 20_COND_DEPS_TRACKING_1[./mysql++.bkl] ### COND_DEPS_TRACKING_1="#" if test "x$DEPS_TRACKING" = "x1" ; then COND_DEPS_TRACKING_1="" fi AC_SUBST(COND_DEPS_TRACKING_1) dnl ### begin block 20_COND_PLATFORM_MACOSX_0_USE_SOVERCYGWIN_0_USE_SOVERSION_1[./mysql++.bkl] ### COND_PLATFORM_MACOSX_0_USE_SOVERCYGWIN_0_USE_SOVERSION_1="#" if test "x$PLATFORM_MACOSX" = "x0" -a "x$USE_SOVERCYGWIN" = "x0" -a "x$USE_SOVERSION" = "x1" ; then COND_PLATFORM_MACOSX_0_USE_SOVERCYGWIN_0_USE_SOVERSION_1="" fi AC_SUBST(COND_PLATFORM_MACOSX_0_USE_SOVERCYGWIN_0_USE_SOVERSION_1) dnl ### begin block 20_COND_PLATFORM_MACOSX_0_USE_SOVERSION_1[./mysql++.bkl] ### COND_PLATFORM_MACOSX_0_USE_SOVERSION_1="#" if test "x$PLATFORM_MACOSX" = "x0" -a "x$USE_SOVERSION" = "x1" ; then COND_PLATFORM_MACOSX_0_USE_SOVERSION_1="" fi AC_SUBST(COND_PLATFORM_MACOSX_0_USE_SOVERSION_1) dnl ### begin block 20_COND_PLATFORM_MACOSX_1[./mysql++.bkl] ### COND_PLATFORM_MACOSX_1="#" if test "x$PLATFORM_MACOSX" = "x1" ; then COND_PLATFORM_MACOSX_1="" fi AC_SUBST(COND_PLATFORM_MACOSX_1) dnl ### begin block 20_COND_PLATFORM_MACOSX_1_USE_SOVERSION_1[./mysql++.bkl] ### COND_PLATFORM_MACOSX_1_USE_SOVERSION_1="#" if test "x$PLATFORM_MACOSX" = "x1" -a "x$USE_SOVERSION" = "x1" ; then COND_PLATFORM_MACOSX_1_USE_SOVERSION_1="" fi AC_SUBST(COND_PLATFORM_MACOSX_1_USE_SOVERSION_1) dnl ### begin block 20_COND_PLATFORM_MAC_0[./mysql++.bkl] ### COND_PLATFORM_MAC_0="#" if test "x$PLATFORM_MAC" = "x0" ; then COND_PLATFORM_MAC_0="" fi AC_SUBST(COND_PLATFORM_MAC_0) dnl ### begin block 20_COND_PLATFORM_MAC_1[./mysql++.bkl] ### COND_PLATFORM_MAC_1="#" if test "x$PLATFORM_MAC" = "x1" ; then COND_PLATFORM_MAC_1="" fi AC_SUBST(COND_PLATFORM_MAC_1) dnl ### begin block 20_COND_PLATFORM_OS2_1[./mysql++.bkl] ### COND_PLATFORM_OS2_1="#" if test "x$PLATFORM_OS2" = "x1" ; then COND_PLATFORM_OS2_1="" fi AC_SUBST(COND_PLATFORM_OS2_1) dnl ### begin block 20_COND_USE_SOTWOSYMLINKS_1[./mysql++.bkl] ### COND_USE_SOTWOSYMLINKS_1="#" if test "x$USE_SOTWOSYMLINKS" = "x1" ; then COND_USE_SOTWOSYMLINKS_1="" fi AC_SUBST(COND_USE_SOTWOSYMLINKS_1) dnl ### begin block 20_COND_USE_SOVERCYGWIN_1_USE_SOVERSION_1[./mysql++.bkl] ### COND_USE_SOVERCYGWIN_1_USE_SOVERSION_1="#" if test "x$USE_SOVERCYGWIN" = "x1" -a "x$USE_SOVERSION" = "x1" ; then COND_USE_SOVERCYGWIN_1_USE_SOVERSION_1="" fi AC_SUBST(COND_USE_SOVERCYGWIN_1_USE_SOVERSION_1) dnl ### begin block 20_COND_USE_SOVERLINUX_1[./mysql++.bkl] ### COND_USE_SOVERLINUX_1="#" if test "x$USE_SOVERLINUX" = "x1" ; then COND_USE_SOVERLINUX_1="" fi AC_SUBST(COND_USE_SOVERLINUX_1) dnl ### begin block 20_COND_USE_SOVERSION_0[./mysql++.bkl] ### COND_USE_SOVERSION_0="#" if test "x$USE_SOVERSION" = "x0" ; then COND_USE_SOVERSION_0="" fi AC_SUBST(COND_USE_SOVERSION_0) dnl ### begin block 20_COND_USE_SOVERSION_1_USE_SOVERSOLARIS_1[./mysql++.bkl] ### COND_USE_SOVERSION_1_USE_SOVERSOLARIS_1="#" if test "x$USE_SOVERSION" = "x1" -a "x$USE_SOVERSOLARIS" = "x1" ; then COND_USE_SOVERSION_1_USE_SOVERSOLARIS_1="" fi AC_SUBST(COND_USE_SOVERSION_1_USE_SOVERSOLARIS_1) dnl ### begin block 20_COND_USE_SOVERSOLARIS_1[./mysql++.bkl] ### COND_USE_SOVERSOLARIS_1="#" if test "x$USE_SOVERSOLARIS" = "x1" ; then COND_USE_SOVERSOLARIS_1="" fi AC_SUBST(COND_USE_SOVERSOLARIS_1) dnl ### begin block 20_COND_WINDOWS_IMPLIB_1[./mysql++.bkl] ### COND_WINDOWS_IMPLIB_1="#" if test "x$WINDOWS_IMPLIB" = "x1" ; then COND_WINDOWS_IMPLIB_1="" fi AC_SUBST(COND_WINDOWS_IMPLIB_1) |
Added 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) ]) |
Added 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 |
Changes to config/mysql++.m4.
1 2 3 4 | #-###################################################################### # mysql++.m4 - Example autoconf macro showing how to find MySQL++ # library and header files. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 | #-###################################################################### # mysql++.m4 - Example autoconf macro showing how to find MySQL++ # library and header files. # # Copyright (c) 2004-2009 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 |
︙ | ︙ | |||
33 34 35 36 37 38 39 | 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 | | | < < | < > | | | < > | < | > > | | | | | | | | | | | | | | | | | | | | | | | | | > > > > | < < < < < < < < < < | | | | | | | | | | | | | > > > > > > > > | < | | | | | 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 | 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.3, 2009/11/22 dnl @author Warren Young <mysqlpp@etr-usa.com> AC_DEFUN([MYSQLPP_DEVEL], [ dnl dnl Set up configure script macros dnl AC_ARG_WITH(mysqlpp, [ --with-mysqlpp=<path> path containing MySQL++ header and library subdirs], [MYSQLPP_lib_check="$with_mysqlpp/lib64 $with_mysqlpp/lib $with_mysqlpp/lib64/mysql++ $with_mysqlpp/lib/mysql++" MYSQLPP_inc_check="$with_mysqlpp/include $with_mysqlpp/include/mysql++"], [MYSQLPP_lib_check="/usr/local/mysql++/lib64 /usr/local/mysql++/lib /usr/local/lib64/mysql++ /usr/local/lib/mysql++ /opt/mysql++/lib64 /opt/mysql++/lib /usr/lib64/mysql++ /usr/lib/mysql++ /usr/local/lib64 /usr/local/lib /usr/lib64 /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/lib64 $with_mysqlpp_lib/lib $with_mysqlpp_lib/lib64/mysql $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"]) dnl dnl Look for MySQL++ library dnl AC_CACHE_CHECK([for MySQL++ library location], [ac_cv_mysqlpp_lib], [ for dir in $MYSQLPP_lib_check do if test -d "$dir" && \ ( test -f "$dir/libmysqlpp.so" || test -f "$dir/libmysqlpp.a" ) then ac_cv_mysqlpp_lib=$dir break fi done if test -z "$ac_cv_mysqlpp_lib" then AC_MSG_ERROR([Didn't find the MySQL++ library dir in '$MYSQLPP_lib_check']) fi case "$ac_cv_mysqlpp_lib" in /* ) ;; * ) AC_MSG_ERROR([The MySQL++ library directory ($ac_cv_mysqlpp_lib) must be an absolute path.]) ;; esac ]) AC_SUBST([MYSQLPP_LIB_DIR],[$ac_cv_mysqlpp_lib]) dnl dnl Look for MySQL++ header file directory dnl AC_CACHE_CHECK([for MySQL++ include path], [ac_cv_mysqlpp_inc], [ for dir in $MYSQLPP_inc_check do if test -d "$dir" && test -f "$dir/mysql++.h" then ac_cv_mysqlpp_inc=$dir break fi done if test -z "$ac_cv_mysqlpp_inc" then AC_MSG_ERROR([Didn't find the MySQL++ header dir in '$MYSQLPP_inc_check']) fi case "$ac_cv_mysqlpp_inc" in /* ) ;; * ) AC_MSG_ERROR([The MySQL++ header directory ($ac_cv_mysqlpp_inc) must be an absolute path.]) ;; esac ]) AC_SUBST([MYSQLPP_INC_DIR],[$ac_cv_mysqlpp_inc]) dnl dnl Now check that the above checks resulted in -I and -L flags that dnl let us build actual programs against MySQL++. dnl case "$ac_cv_mysqlpp_lib" in /usr/lib) ;; *) LDFLAGS="$LDFLAGS -L${ac_cv_mysqlpp_lib}" ;; esac CPPFLAGS="$CPPFLAGS -I${ac_cv_mysqlpp_inc} -I${MYSQL_C_INC_DIR}" AC_MSG_CHECKING([that we can build MySQL++ programs]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([#include <mysql++.h>], [mysqlpp::Connection c(false)])], AC_MSG_RESULT([yes]), AC_MSG_ERROR([no])) ]) dnl End MYSQLPP_DEVEL |
Changes to 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | dnl @synopsis MYSQL_C_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 by tacking common dnl suffixes on like /lib and /include. dnl --with-mysql-lib: Same as --with-mysql, but for library only. dnl --with-mysql-include: Same as --with-mysql, but for headers only. dnl dnl @version 1.5, 2016/12/31 dnl @author Warren Young <mysqlpp@etr-usa.com> AC_DEFUN([MYSQL_C_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 /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 /usr/mysql/lib/mysql /opt/mysql/lib /opt/mysql/lib/mysql /sw/lib /sw/lib/mysql" MYSQL_inc_check="/usr/include/mysql /usr/local/include/mysql /usr/local/mysql/include /usr/local/mysql/include/mysql /usr/mysql/include/mysql /opt/mysql/include/mysql /sw/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_NAME=mysqlclient_r else MYSQL_C_LIB_NAME=mysqlclient fi # # Look for MySQL C API headers # AC_MSG_CHECKING([for MySQL include directory]) MYSQL_C_INC_DIR= for m in $MYSQL_inc_check do if test -d "$m" && test -f "$m/mysql.h" then MYSQL_C_INC_DIR=$m break fi done if test -z "$MYSQL_C_INC_DIR" then AC_MSG_ERROR([Didn't find the MySQL include dir in '$MYSQL_inc_check']) fi case "$MYSQL_C_INC_DIR" in /* ) ;; * ) AC_MSG_ERROR([The MySQL include directory ($MYSQL_C_INC_DIR) must be an absolute path.]) ;; esac AC_MSG_RESULT([$MYSQL_C_INC_DIR]) # # Look for MySQL C API library # AC_MSG_CHECKING([for MySQL C API library directory]) save_CPPFLAGS=$CPPFLAGS save_LIBS=$LIBS save_LDFLAGS=$LDFLAGS CPPFLAGS="$CPPFLAGS -I$MYSQL_C_INC_DIR" MYSQL_C_LIB_DIR= for m in $MYSQL_lib_check do LDFLAGS="$save_LDFLAGS -L$m" LIBS="$save_LIBS -l$MYSQL_C_LIB_NAME" AC_TRY_LINK( [ #include <mysql.h> ], [ mysql_store_result(0); ], [ AC_MSG_RESULT([$m]) MYSQL_C_LIB_DIR=$m break ], [ LIBS="$save_LIBS -l$MYSQL_C_LIB_NAME -lz" AC_TRY_LINK( [ #include <mysql.h> ], [ mysql_store_result(0); ], [ AC_MSG_RESULT([$m]) MYSQLPP_EXTRA_LIBS="$MYSQLPP_EXTRA_LIBS -lz" MYSQL_C_LIB_DIR=$m break ], [ ] ) ]) done CPPFLAGS=$save_CPPFLAGS LIBS=$save_LIBS LDFLAGS=$save_LDFLAGS if test -z "$MYSQL_C_LIB_DIR" then AC_MSG_RESULT([no joy]) AC_MSG_ERROR([Didn't find $MYSQL_C_LIB_NAME library in '$MYSQL_lib_check']) fi case "$MYSQL_C_LIB_DIR" in /* ) ;; * ) AC_MSG_ERROR([The MySQL library directory ($MYSQL_C_LIB_DIR) must be an absolute path.]) ;; esac if [ "$MYSQL_C_LIB_DIR" = "/usr/lib" -o \ "$MYSQL_C_LIB_DIR" = "/usr/lib64" ] then # Remove redundant lib paths MYSQL_C_LIB_DIR= fi AC_SUBST(MYSQL_C_INC_DIR) AC_SUBST(MYSQL_C_LIB_DIR) AC_SUBST(MYSQL_C_LIB_NAME) ]) dnl MYSQL_C_API_LOCATION |
Deleted config/mysql_shutdown.m4.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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_NAME, 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 |
Added 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) ]) |
Added 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 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 | # 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++, 3.2.3, plusplus@lists.mysql.com, mysql++) AC_CONFIG_HEADER(config.h) AC_CONFIG_MACRO_DIR([config]) AC_CANONICAL_SYSTEM # Enable libtool to decide shared library compile flags (ie -fPIC) AC_PROG_LIBTOOL AC_SUBST([LIBTOOL_DEPS]) # 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) # Check for Standard C support AC_PROG_CC 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" AC_CHECK_HEADERS(synch.h) AC_CHECK_HEADERS(unistd.h) fi # Let caller provide -f to lib/*.pl scripts in a uniform way AC_ARG_WITH([field-limit], AS_HELP_STRING([--with-field-limit=<n>], [set max template query and SSQLS field count]), [], []) if test -n "$with_field_limit" then ( cd lib ; ./querydef.pl -f $with_field_limit ; ./ssqls.pl -f $with_field_limit ) fi # Try to find local getopt(); if we fail, we'll use the one in lib/cmdline.* AC_CHECK_FUNC(getopt, [AC_DEFINE(HAVE_POSIX_GETOPT, [], Define if getopt() is available in unistd.h)], [AC_CHECK_LIB(iberty, getopt, [AC_DEFINE(HAVE_LIBIBERTY_GETOPT, [], Define if getopt() is available in libiberty.h)], [])]) # Checks for libraries and local system features LIB_MATH LIB_SOCKET_NSL MYSQL_C_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_PROG_CXX AC_LANG_CPLUSPLUS STL_SLIST_EXTENSION # Include Bakefile macros AC_BAKEFILE([m4_include(config/autoconf_inc.m4)]) # # Configure process complete; write out files generated from *.in. # AC_OUTPUT([\ doc/userman/userman.dbx \ install.hta \ lib/Doxyfile \ lib/mysql++.h \ ssx/Doxyfile \ abi.xml \ mysql++.spec \ Makefile \ version ]) chmod +x version |
Deleted configure.in.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added doc/README-devel-RPM.txt.
> > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 | mysql++-devel 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 MySQL++ header files are in /usr/include/mysql++, the library is in /usr/lib, and the example programs' source code is in /usr/share/doc/mysql++-devel-*/examples. For more information on the examples, see the README-examples.txt file in the directory containing the examples. |
Added doc/README-manuals-RPM.txt.
> > > > > | 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. |
Deleted doc/README.devel.
|
| < < < < < < < < < < < |
Deleted doc/README.mysql++.
|
| < < < < < |
Changes to doc/ssqls-pretty.
1 2 3 4 5 6 7 | #!/usr/bin/perl use FileHandle; use IPC::Open2; if ($ARGV[0] =~ /^--command\=(.+)/) { $command = $1; } else { | | > > > > | > | | 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 | #!/usr/bin/perl use FileHandle; use IPC::Open2; if ($ARGV[0] =~ /^--command\=(.+)/) { $command = $1; } else { $command = "g++ -E -I /usr/include/mysql"; } if (-e 'lib/mysql++.h') { $command .= " -I lib"; } else { $command .= " -I /usr/include/mysql++/"; } $/ = undef; $orgcode = <STDIN>; ($macro) = $orgcode =~ /(sql_create_.+? *\(.+?\))/s; $out = << "---"; #include <ssqls.h> $macro --- $/ = "\n"; |
︙ | ︙ |
Changes to 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 | ## ------------------------ ## Input files ## ------------------------ HTML_DIR=../html/userman BASENAME=userman DOCFILE=$(BASENAME).dbx PDFFILE=../pdf/$(BASENAME).pdf FOFILE=$(BASENAME).fo COMMON_SS=common.xsl FO_SS=fo.xsl HTML_SS=html.xsl EX_TXT=cgi_jpeg.txt cpool.txt deadlock.txt fieldinf.txt for_each.txt \ load_jpeg.txt multiquery.txt resetdb.txt simple1.txt \ simple2.txt simple3.txt ssqls1.txt ssqls2.txt ssqls3.txt \ ssqls4.txt ssqls5.txt ssqls6.txt stock.txt store_if.txt \ tquery1.txt transaction.txt ## ------------------------ ## Major output rules ## ------------------------ html: $(EX_TXT) $(HTML_DIR)/index.html pdf: $(EX_TXT) $(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 $(EX_TXT) $(PDFFILE) ## ------------------------ ## How to make output files ## ------------------------ $(PDFFILE): *.dbx *.in $(FO_SS) $(COMMON_SS) xsltproc --xinclude $(FO_SS) $(DOCFILE) > $(FOFILE) mkdir -p ../pdf ./fo2pdf $(FOFILE) $(PDFFILE) $(HTML_DIR)/index.html: *.dbx *.in *.mod *.txt *.xsl @xmllint --xinclude --nonet --postvalid --noent --noout $(DOCFILE) xsltproc --xinclude --nonet -o $(HTML_DIR)/ $(HTML_SS) $(DOCFILE) ## ------------------------ ## Dependency rules ## ------------------------ $(EX_TXT): @./mktxt $@ userman.dbx: userman.dbx.in ( cd ../.. ; ./config.status ) |
Added doc/userman/Makefile.hello.mingw.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | SHELL := $(COMSPEC) MYSQL_DIR := "c:/Program Files/MySQL/MySQL Connector C 6.1" CXXFLAGS := -I$(MYSQL_DIR)/include -Ic:/MySQL++/include LDFLAGS := -L$(MYSQL_DIR)/lib -Lc:/MySQL++/lib/MinGW LDLIBS := -lmysql -lmysqlpp EXECUTABLE := hello all: $(EXECUTABLE) clean: del $(EXECUTABLE) |
Added doc/userman/Makefile.hello.posix.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | CXXFLAGS := -I/usr/include/mysql -I/usr/local/include/mysql++ LDFLAGS := -L/usr/local/lib LDLIBS := -lmysqlpp -lmysqlclient EXECUTABLE := hello all: $(EXECUTABLE) clean: rm -f $(EXECUTABLE) *.o |
Deleted doc/userman/README.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added doc/userman/breakages.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <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 id="api-changes"> <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 id="api-1.7.10"> <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 id="api-1.7.19"> <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 id="api-1.7.20"> <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 id="api-2.0.0"> <title>v2.0.0</title> <sect4 id="api-2.0.0-Connection"> <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 id="api-2.0.0-Exception"> <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 id="api-2.0.0-Query"> <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 id="api-2.0.0-Result"> <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 id="api-2.0.0-Row"> <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 id="api-2.0.0-misc"> <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 id="api-2.2.0"> <title>v2.2.0</title> <para>Code like this will have to change:</para> <programlisting> query << "delete from mytable where myfield=%0:myvalue"; query.parse(); query.def["myvalue"] = some_value; query.execute();</programlisting> <para>...to something more like this:</para> <programlisting> query << "delete from mytable where myfield=%0"; query.parse(); query.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 id="api-2.3.0"> <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> <sect3 id="api-3.0.0"> <title>v3.0.0</title> <sect4 id="api-3.0.0-names"> <title>Class name changes</title> <para>Several classes changed names in this release:</para> <itemizedlist> <listitem><para><classname>ColData</classname> is now <classname>String</classname>.</para></listitem> <listitem><para><classname>NullisBlank</classname> is now <classname>NullIsBlank</classname>. (Note the capital <emphasis>I</emphasis>.) Similar changes for <classname>NullisNull</classname> and <classname>NullisZero</classname>.</para></listitem> <listitem><para><classname>ResNSel</classname> is now <classname>SimpleResult</classname>.</para></listitem> <listitem><para><classname>Result</classname> is now <classname>StoreQueryResult</classname>.</para></listitem> <listitem><para><classname>ResUse</classname> is now <classname>UseQueryResult</classname>.</para></listitem> <listitem><para><classname>SQLString</classname> is now <classname>SQLTypeAdapter</classname>.</para></listitem> </itemizedlist> <para>When first building existing code against this version, you may find it helpful to define the macro <varname>MYSQLPP_OLD_CLASS_NAMES</varname> in your program’s build options. This will turn on some macros that set up aliases for the new class names matching their corresponding old names. Then, when you’ve fixed up any other issues that may prevent your program from building with the new MySQL++, you can turn it back off and fix up any class name differences.</para> <para>If you were only using <classname>ColData</classname> in a BLOB context, you should use <classname>sql_blob</classname> or one of the related typedefs defined in <filename>lib/sql_types.h</filename> instead, to insulate your code from changes like these.</para> <para>The <classname>SQLString</classname> change shouldn’t affect you, as this class was not designed to be used by end user code. But, due to the old name and the fact that it used to derive from <classname>std::string</classname>, some might have been tempted to use it as an enhanced <classname>std::string</classname>. Such code will undoubtedly break, but can probably be fixed by just changing it to use <classname>std::string</classname> instead.</para> </sect4> <sect4 id="api-3.0.0-Connection"> <title>Connection class changes</title> <para>The option setting mechanism has been redesigned. (Yes, again.) There used to be an enum in <classname>Connection</classname> with a value for each option we understood, and an overload of <methodname>Connection::set_option()</methodname> for each argument type we understood. It was possible to pass any option value to any <methodname>set_option()</methodname> overload, and the problem would only be detected at run time. Now each option is represented by a class derived from the new <classname>Option</classname> abstract base class, and <methodname>set_option()</methodname> simply takes a pointer to one of these objects. See <filename>examples/multiquery.cpp</filename> for the syntax. Since each <classname>Option</classname> subclass takes only the parameter types it actually understands, it’s now completely type-safe at compile time.</para> <para>The new option setting mechanism also has the virtue of being more powerful so it let us replace several existing things within <classname>Connection</classname> with new options:</para> <itemizedlist> <listitem><para>Replaced <methodname>enable_ssl()</methodname> with <classname>SslOption</classname>.</para></listitem> <listitem><para>Replaced the <varname>compress</varname> parameter to the <classname>Connection</classname> create-and-connect constructor and <methodname>Connection::connect()</methodname> method with <classname>CompressOption</classname>.</para></listitem> <listitem><para>Replaced the <varname>connect_timeout</varname> parameter with <classname>ConnectTimeoutOption</classname>.</para></listitem> <listitem><para>Defined <classname>Option</classname> subclasses for each of the flags you would previously set using the <varname>client_flag</varname> parameter. There are about a dozen of these, so instead of listing them, look in <filename>lib/options.h</filename> for something with a similar name.</para></listitem> </itemizedlist> <para>Collapsed <classname>Connection</classname>’s <varname>host</varname>, <varname>port</varname>, and <varname>socket_name</varname> parameters down into a new combined <varname>server</varname> parameter which is parsed to determine what kind of connection you mean. These interfaces are still compatible with v2.3 and earlier up through the port parameter.</para> <para>Moved <methodname>Connection::affected_rows()</methodname>, <methodname>info()</methodname> and <methodname>insert_id()</methodname> methods to class <classname>Query</classname>, as they relate to the most recently-executed query.</para> <para>Changed the return type of <methodname>Connection::ping()</methodname> from <type>int</type> to <type>bool</type>. If you were calling <methodname>ping()</methodname> in <type>bool</type> context or using its return value in <type>bool</type> context, you will need to reverse the sense of the test because the previous return code used zero to mean success. Now it returns <type>true</type> to indicate success.</para> <para>Renamed several methods:</para> <itemizedlist> <listitem><para>Use <methodname>client_version()</methodname> instead of <methodname>api_version()</methodname> or <methodname>client_info()</methodname>.</para></listitem> <listitem><para>Use <methodname>ipc_version()</methodname> instead of <methodname>host_info()</methodname>.</para></listitem> <listitem><para>Use <methodname>protocol_version()</methodname> instead of <methodname>proto_info()</methodname>.</para></listitem> <listitem><para>Use <methodname>server_version()</methodname> instead of <methodname>server_info()</methodname>.</para></listitem> <listitem><para>Use <methodname>status()</methodname> instead of <methodname>stat()</methodname>.</para></listitem> </itemizedlist> <para>Also, removed <methodname>close()</methodname> in favor of <methodname>disconnect()</methodname>, which has always done the same thing.</para> </sect4> <sect4 id="api-3.0.0-DateTime"> <title>Date and Time class changes</title> <para>The <type>sql_timestamp</type> typedef is now an alias for <classname>DateTime</classname>, not <classname>Time</classname>.</para> <para>There used to be implicit conversion constructors from <classname>ColData</classname> (now <classname>String</classname>), <classname>std::string</classname> and <type>const char*</type> for the <classname>Date</classname>, <classname>DateTime</classname>, and <classname>Time</classname> classes. It’s still possible to do these conversions, but only explicitly. (This had to be done to make <classname>Null<T></classname> work in SSQLSes.)</para> <para>The most likely place to run into problems as a result of this change is in code like this:</para> <programlisting> void some_function(const mysqlpp::DateTime& dt); some_function("2007-12-22");</programlisting> <para>The function call needs to be changed to:</para> <programlisting> some_function(mysqlpp::DateTime("2007-12-22"));</programlisting> </sect4> <sect4 id="api-3.0.0-Exception"> <title>Exception changes</title> <para>If an error occurs during the processing of a “use” query (as opposed to the initial execution) we throw the new <classname>UseQueryError</classname> exception instead of <classname>BadQuery</classname>.</para> <para>If you pass bad values to the <classname>Row</classname> ctor so that it can’t initialize itself properly, it throws the <classname>ObjectNotInitialized </classname> exception instead of <classname>BadQuery</classname>.</para> <para>Together, these two changes mean that <classname>BadQuery</classname> is now used solely to indicate a problem executing the actual SQL query statement.</para> </sect4> <sect4 id="api-3.0.0-Field"> <title>Field and Fields class changes</title> <para><classname>Field</classname> is now a real C++ class, not just a typedef for the corresponding C API class. Major portability impacts are:</para> <itemizedlist> <listitem><para>It has no public data members. Where sensible, there is a public accessor function of the same name as the corresponding field in the C API structure.</para></listitem> <listitem><para>The main exception to this is the <varname>flags</varname> data member. This is a bitfield in the C API data structure and you had to use MySQL-specific constants to break values out of it. MySQL++’s new <classname>Field</classname> class provides a public member function returning <type>bool</type> for each of these flags.</para></listitem> <listitem><para>The new class doesn’t include all of the data members from the C API version. We left out those that aren’t used within MySQL++ or its examples, or whose function we couldn’t understand. Basically, if we couldn’t document a reason to use it, we left it out.</para></listitem> </itemizedlist> <para><classname>Fields</classname> used to be a <classname>std::vector</classname> work-alike which worked with the C API to access fields and return them as though they were simply contained directly within the <classname>Fields</classname> object. Now that we have a real MySQL++ class to hold information about each field without reference to the C API, we were able to replace the <classname>Fields</classname> class with:</para> <programlisting> typedef std::vector<Field> Fields;</programlisting> <para>If anything, this should give a pure superset of the old functionality, but it’s possible it could break end user code.</para> </sect4> <sect4 id="api-3.0.0-Query"> <title>Query class changes</title> <para>If you were using <type>char</type> as an 8-bit integer in query building, there are several places in MySQL++ v3 where it will now be treated as a single-character string. MySQL++ has had the <classname>tiny_int</classname> class for many years now specifically to provide a true 8-bit integer without the semantic confusion surrounding the old C <type>char</type> type. Either use <classname>tiny_int</classname>, or use the SQL type aliases <type>sql_tinyint</type> and <type>sql_tinyint_unsigned</type> instead.</para> <para>The ‘r’ and ‘R’ template query parameter modifiers were removed. They made the library do quoting and both quoting and escaping (respectively) regardless of the data type of the parameter. There are no corresponding <classname>Query</classname> stream manipulators, so for symmetery we had to decide whether to add such manipulators or remove the tquery modifiers. There should never be a reason to force quoting or escaping other than to work around a MySQL++ bug, and it’s better to just fix the bug than work around it, so removed the tquery modifiers.</para> <para><methodname>Query::store_next()</methodname> and <methodname>Result::fetch_row()</methodname> no longer throw the <classname>EndOfResults</classname> and <classname>EndOfResultSets</classname> exceptions; these are not exceptional conditions! These methods simply return <type>false</type> when you hit the end of the result set now.</para> <para>Renamed <varname>Query::def</varname> to <varname>Query::template_defaults</varname> to make its purpose clearer.</para> <para>Removed <methodname>Query::preview()</methodname>. The most direct replacement for this set of overloaded methods is the parallel set of <methodname>str()</methodname> methods, which were just aliases before. (Chose <methodname>str()</methodname> over <methodname>preview()</methodname> because it’s standard C++ nomenclature.) But if you’re just looking to get a copy of a built query string and you aren’t using template queries, you can now insert the <classname>Query</classname> into a stream and get the same result.</para> <para>For example, a lot of code in the examples that used to say things like:</para> <programlisting> cout << query.preview() << endl;</programlisting> <para>now looks like this:</para> <programlisting> cout << query << endl;</programlisting> </sect4> <sect4 id="api-3.0.0-Result"> <title>Result, ResUse, and ResNSel class changes</title> <para>In addition to the class name changes described above, <classname>UseQueryResult</classname> is no longer <classname>StoreQueryResult</classname>’s base class. There is a new abstract class called <classname>ResultBase</classname> containing much of what used to be in <classname>ResUse</classname>, and it is the base of both of these concrete result set types. This should only affect your code if you were using <classname>ResUse</classname> references to refer to <classname>Result</classname> objects.</para> <para>Removed a bunch of duplicate methods:</para> <itemizedlist> <listitem><para>Use <methodname>num_fields()</methodname> instead of <methodname>columns()</methodname>.</para></listitem> <listitem><para>Use <methodname>field_names()</methodname> instead of <methodname>names()</methodname>.</para></listitem> <listitem><para>Use <methodname>num_rows()</methodname> instead of <methodname>rows()</methodname>.</para></listitem> <listitem><para>Use <methodname>field_types()</methodname> instead of <methodname>types()</methodname>.</para></listitem> </itemizedlist> <para>Renamed several methods for “grammar” reasons. For example, some methods returned a single object but had a “plural” name, implying that it returned a container of objects. In cases like this, we changed the name to agree with the return value. Some of these also fall into the duplicate method category above:</para> <itemizedlist> <listitem><para>Use <methodname>field(unsigned int)</methodname> instead of <methodname>fields(unsigned int)</methodname>.</para></listitem> <listitem><para>Use <methodname>field_num(const std::string&)</methodname> instead of <methodname>names(const std::string&)</methodname>.</para></listitem> <listitem><para>Use <methodname>field_name(int)</methodname> instead of <methodname>names(int)</methodname>.</para></listitem> <listitem><para>Use <methodname>field_type(int)</methodname> instead of <methodname>types(int)</methodname>.</para></listitem> </itemizedlist> <para>Removed several “smelly” methods:</para> <itemizedlist> <listitem><para><methodname>purge()</methodname>: was an internal implementation detail, not something for end user code to call</para></listitem> <listitem><para><methodname>raw_result()</methodname>: end user code shouldn’t be digging down to the C API data structures, but if you really need something like this, look at the implementation of <methodname>Query::storein()</methodname>. Its workings will probably be educational.</para></listitem> <listitem><para><methodname>reset_names()</methodname>: no reason to call this, especially now that the field name list is initialized once at startup and then never changed</para></listitem> <listitem><para><methodname>reset_field_names()</methodname>: just an alias for previous</para></listitem> <listitem><para><methodname>reset_types()</methodname>: same argument as for <methodname>reset_names()</methodname></para></listitem> <listitem><para><methodname>reset_field_types()</methodname>: just an alias for previous</para></listitem> </itemizedlist> <para><methodname>ResUse::field_num()</methodname> would unconditionally throw a <classname>BadFieldName</classname> exception when you asked for a field that doesn’t exist. Now, if exceptions are disabled on the object, it just returns -1.</para> <para><classname>SimpleResult</classname>’s member variables are all now private, and have read-only accessor functions of the same name.</para> <para>Code like this used to work:</para> <programlisting> mysqlpp::Row row; mysqlpp::Result::size_type i; for (i = 0; row = res[i]; ++i) { // Do something with row here }</programlisting> <para>That is, indexing past the end of a “store” result set would just return an empty row object, which tests as false in <type>bool</type> context, so it ends the loop. Now that <classname>StoreQueryResult</classname> is a <classname>std::vector</classname> derivative, this either crashes your program or causes the standard library to throw an exception, depending on what debugging features your version of STL has. The proper technique is:</para> <programlisting> mysqlpp::Row row; mysqlpp::StoreQueryResult::size_type i; for (i = 0; i < res.num_rows(); ++i) { row = res[i]; // Do something with row here }</programlisting> <para>...or, in a more C++ish idiom:</para> <programlisting> mysqlpp::Row row; mysqlpp::StoreQueryResult::const_iterator it; for (it = res.begin(); it != res.end(); ++it) { row = *it; // Do something with row here }</programlisting> </sect4> <sect4 id="api-3.0.0-Row"> <title>Row class changes</title> <para>Removed <methodname>Row::raw_data()</methodname>, <methodname>raw_size()</methodname> and <methodname>raw_string()</methodname>. These were useful with BLOB data back when MySQL++ didn’t handle embedded null characters very well, and when copies of <classname>ColData</classname> objects were expensive. Neither is true now, so they have no value any more. Equivalent calls are:</para> <programlisting> mysqlpp::String s = row[0]; s.data(); // raw_data() equivalent s.length(); // raw_size() equivalent std::string(s.data(), s.length()); // raw_string() equivalent</programlisting> <para><methodname>Row::operator[](const char*)</methodname> would unconditionally throw a <classname>BadFieldName</classname> exception when you asked for a field that doesn’t exist. Now, if exceptions are disabled on the <classname>Row</classname> object, it just returns a reference to an empty <classname>String</classname> object. You can tell when this happens because such an object tests as false in <type>bool</type> context.</para> </sect4> <sect4 id="api-3.0.0-SSQLS"> <title>Specialized SQL Structure (SSQLS) changes</title> <para>Renamed <filename>custom*</filename> to <filename>ssqls*</filename>. There is a backwards-compatibility header <filename>custom.h</filename> which includes <filename>ssqls.h</filename> for you, but it will go away in a future version of MySQL++.</para> <para>SSQLSes get populated by field name now, not by field order. In v2, it was absolutely required that your SSQLS had its fields declared in exactly the same order as the fields in the database server, and there could be no gaps. An <command>ALTER TABLE</command> command would almost always necessitate redefining the corresponding SSQLS and rebuilding your program. Some alterations actually made using SSQLS impossible. For the most part, this change just gives your program additional flexibility in the face of future changes. However, code that was taking advantage of this low-level fact will break when moving to v3. Before I explain how, let’s go over the high-level functional changes you’ll find in v3’s SSQLS mechanism.</para> <para>Because MySQL++ no longer needs the SSQLS field order to match the SQL field order, the <function>sql_create_c_order_*</function> SSQLS creation macro was dropped in v3. We were also able to drop the ordering parameters from <function>sql_create_complete_*</function>. That in turn means there is no longer a difference between the way it and <function>sql_create_c_names_*</function> work, so the latter was also dropped. Thus, there are now only two groups of SSQLS creation macros left: <function>sql_create_*</function>, which works pretty much as it always has, and <function>sql_create_complete_*</function>, which is the same except for the lack of ordering parameters.</para> <para>In general, you should be using <function>sql_create_*</function> for all SSQLSes unless you need to use different names for data members in C++ than you use for the corresponding columns in SQL. In that case, use <function>sql_create_complete_*</function> instead.</para> <para>In v2, it was possible to have different SQL column names than SSQLS data member names while still using <function>sql_create_*</function> if you only used SSQLS for data retrieval.<footnote><para>In MySQL++ v2, data retreival (<methodname>Query::storein()</methodname>, <methodname>SSQLS(const Row& other)</methodname>, etc.) worked fine regardless of whether your SSQLS field names matched those in the corresponding SQL table, because the SSQLS was populated by position, not by field name. Thus, if all you used SSQLS for was data retrieval, you could define your structures with <function>sql_create_*</function> in v2. This was never recommended, because such an SSQLS wouldn’t work with other features of MySQL++ like <methodname>Query::insert()</methodname> because they depend on being able to map names from C++ to SQL and back. You needed to use <function>sql_create_c_names_*</function> to make these features work in v2 in the face of a naming scheme difference between C++ and SQL.</para></footnote> In v3, you must use <function>sql_create_complete_*</function> for absolutely all uses of SSQLS when you want the C++ field names to differ from the SQL column names.</para> <para>The new <classname>Null<T></classname> support in SSQLSes causes an internal compiler error in Visual C++ 2003. (VC++ 2005 and newer have no trobule with it.) A poll on the mailing list says there aren’t many people still stuck on this version, so we just ifdef’d out the SSQLS mechanism and all the examples that use it when built with VC++ 2003. If this affects you, see <xref linkend="ssqls-vc2003"/> for suggestions on ways to cope.</para> <para>If you are using types other than MySQL++’s <type>sql_*</type> ones <footnote><para>These typedefs have been available since MySQL++ v2.1.</para></footnote> in your SSQLSes, code that previously worked may now see <classname>TypeLookupFailed</classname> exceptions. (This can be thrown even if exceptions are otherwise disabled in MySQL++.) This version of MySQL++ is stricter about mapping SQL to C++ type information, and vice versa. If the library can’t find a suitable mapping from one type system to the other, it throws this exception, because its only other option would be to crash or raise an assertion. This typically happens when building SQL queries, so you can probably handle it the same way as if the subsequent query excecution failed. If you’re catching the generic <classname>mysqlpp::Exception</classname>, your error handling code might not need to change. If you see this exception, it does mean you need to look into your use of data types, though. The table that controls this is <varname>mysql_type_info::types</varname>, defined at the top of <filename>lib/type_info.cpp</filename>. Every data type in <filename>lib/sql_types.h</filename> has a corresponding record in this table, so if you stick to those types, you’ll be fine. It’s also okay to use types your C++ compiler can convert directly to these predefined types.</para> <para>The <varname>_table</varname> static member variable for each SSQLS is now private. The recommended way to access this remains unchanged: the <function>table()</function> static member function.</para> <para><function>table()</function> used to return a modifiable reference to the table name. Now there are two overloads, one which returns an unmodifiable pointer to the table name, and the other which takes <type>const char*</type> so you can override the default table name. So, the code we used to recommend for changing the SSQLS’s table name:</para> <programlisting> my_ssqls_type::table() = "MyTableName";</programlisting> <para>now needs to be:</para> <programlisting> my_ssqls_type::table("MyTableName");</programlisting> </sect4> <sect4 id="api-3.0.0-misc"> <title>Miscellaneous changes</title> <para>MySQL++ does quoting and escaping much more selectively now. Basically, if the library can tell you’re not building a SQL query using one of the standard methods, it assumes you’re outputting values for human consumption, so it disables quoting and SQL escaping. If you need to build your own mechanism to replace this, quoting is easy to do, and <methodname>Query::escape_string()</methodname> can do SQL escaping for you.</para> <para>Removed <methodname>success()</methodname> in <classname>Connection</classname>, <classname>Query</classname> and <classname>SimpleResult</classname> (neé <classname>ResNSel</classname>) and simply made these classes testable in <type>bool</type> context to get the same information. An additional change in <classname>Connection</classname> is that it used to be considered “unsuccessful” when the connection was down. Since the sense of this test is now whether the object is in a good state, it only returns <type>false</type> when the connection attempt fails. Call <methodname>Connection::is_connected()</methodname> if you just want to test whether the connection is up.</para> <para>The debug mode build of the library now has a "_d" suffix for Visual C++, and Xcode. This lets you have both versions installed without conflict. The release build uses the current naming scheme. If you have an existing program building against MySQL++ on these platforms, you’ll need to change your build options to use the new name in debug mode.</para> <para>Renamed <varname>NO_LONG_LONGS</varname> to <varname>MYSQLPP_NO_LONG_LONGS</varname> to avoid a risk of collision in the global macro namespace.</para> </sect4> </sect3> <sect3 id="api-3.0.7"> <title>v3.0.7</title> <para>Most MySQL++ classes with <methodname>at()</methodname> or <methodname>operator []()</methodname> methods now throw the new <ulink type="structref" url="BadIndex"/> exception when you pass an out-of-range index. These methods variously either did not check their indices, or threw <classname>std::out_of_range</classname> when passed a bad index.</para> <para>I say “most” because there is at least one MySQL++ class that doesn’t follow this rule. <classname>Fields</classname> is just a typedef for a specialization of <classname>std::vector</classname>, and the Standard has its own rules for index checking.</para> </sect3> </sect2> <sect2 id="abi-changes"> <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 id="abi-1.7.18"> <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 id="abi-1.7.19"> <title>v1.7.19</title> <para>Fixed several <type>const</type>-incorrectnesses in the <classname>Query</classname> classes.</para> </sect3> <sect3 id="abi-1.7.22"> <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 id="abi-1.7.24"> <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 id="abi-2.0.0"> <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> <sect3 id="abi-3.0.0"> <title>v3.0.0</title> <para>Removed <varname>reset_query</varname> parameters from <classname>Query</classname> member functions. None of these have been honored at least going back to v1.7.9, so this is not an API change. As of this version, <classname>Query</classname> now automatically detects when it can safely reset itself after executing a query, so it’s not necessary to ask for a reset except when using template queries.</para> <para>Removed overloads of <methodname>Query::execute()</methodname>, <methodname>store()</methodname>, and <methodname>use()</methodname> that take only a <type>const char*</type>. This is not an API change because there was an equivalent call chain for this already. This change just snaps a layer of indirection.</para> <para><methodname>Query::error()</methodname> is now <type>const</type> and returns <type>const char*</type> instead of a <classname>std::string</classname> by value.</para> <para>Removed <classname>Lockable</classname> mechanism as it was conceptually flawed. <classname>Connection</classname> and <classname>Query</classname> consequently no longer derive from <classname>Lockable</classname>. Since it was basically useless in prior versions, it can’t be construed as an API change.</para> </sect3> <sect3 id="abi-3.0.1"> <title>v3.0.1</title> <para><methodname>Connection::thread_aware()</methodname>, <methodname>thread_start()</methodname> and <methodname>thread_end()</methodname> are now static methods, so a program can call them before creating a connection. Ditto for <classname>DBDriver</classname> methods of the same name.</para> <para><methodname>ConnectionPool::release()</methodname> is now virtual, so a subclass can override it.</para> </sect3> <sect3 id="abi-3.0.2"> <title>v3.0.2</title> <para><methodname>ConnectionPool::grab()</methodname> is now virtual; same reason as above.</para> <para><classname>Query</classname> can now be tested in <type>bool</type> context, as was intended for v3.0.0. Had to change the “safe bool” method signature to make it happen, so technically it’s an API change, but it’s still used the same way.</para> </sect3> <sect3 id="abi-3.1.0"> <title>v3.1.0</title> <para>The addition of a few new virtual methods to <classname>ConnectionPool</classname> inadvertently changed the library ABI. I knew adding fields changed the ABI, but erroneously assumed that the inverse of that truth — that adding <emphasis>methods</emphasis> was always safe — was also true. Adding normal methods <emphasis>is</emphasis> safe, but adding <emphasis>virtual</emphasis> methods breaks the ABI because it changes the class’s vtable size.</para> <para>That left us with two bad choices: either we could come out with a 3.1.1 that removed these methods to restore the prior ABI, or we could just declare this the “new ABI” and move on, resolving not to fall into this trap again. We’ve chosen the latter path.</para> </sect3> </sect2> </sect1> |
Changes to doc/userman/common.xsl.
1 2 3 4 5 6 | <?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"> | < < | < | | | < < < < < < < < < < | < | < | < | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?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"> <xsl:param name="section.autolabel" select="1"/> <xsl:param name="section.autolabel.max.depth" select="2"/> <xsl:param name="toc.section.depth" select="2"/> <!-- Hack to let us get <mathphrase>-like behavior in DB 4.2 --> <!-- From: http://www.sagehill.net/docbookxsl/Math.html --> <xsl:template match="phrase[@role = 'math']"> <xsl:call-template name="inline.italicseq"/> </xsl:template> </xsl:stylesheet> |
Added doc/userman/configuration.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="configuration"> <title>Configuring MySQL++</title> <para>The default configuration of MySQL++ is suitable for most purposes, but there are a few things you can change to make it meet special needs.</para> <sect2 id="mysql-loc"> <title>The Location of the MySQL Development Files</title> <para>MySQL++ is built on top of the MySQL C API. (Now called <ulink url="https://dev.mysql.com/downloads/connector/c/">Connector/C</ulink>.) MySQL++ relies on this low-level library for all communication with the database server. Consequently, the build process for MySQL++ may fail if it can’t find the C API headers and library.</para> <para>On platforms that use Autoconf<footnote><para>Linux, Solaris, the BSDs, Mac OS X command line (as opposed to the Xcode IDE), Cygwin... Basically, Unix or anything that works like it.</para></footnote>, the <filename>configure</filename> script can usually figure out the location of the C API development files by itself<footnote><para>I don’t say “Connector/C” here because the name change generally hasn’t percolated out to Unixy systems. It’s more commonly used on Windows systems, since the separate Connector/C download lets them avoid installing a MySQL server just to get development headers and libraries.</para></footnote> It simply tries a bunch of common installation locations until it finds one that works. If your MySQL server was installed in a nonstandard location, you will have to tell the <filename>configure</filename> script where these files are with some combination of the <computeroutput>--with-mysql</computeroutput>, <computeroutput>--with-mysql-include</computeroutput>, and <computeroutput>--with-mysql-lib</computeroutput> flags. See <filename>README-Unix.txt</filename> for details.</para> <para>No other platform allows this sort of auto-discovery, so the build files for these platforms simply hard-code the default installation location for the current GA version of Connector/C at the time that version of MySQL++ was released. For example, the Visual C++ project files currently assume MySQL is in <filename>c:\Program Files\MySQL\MySQL Server 5.1</filename>. If you’re using some other release of MySQL or you installed it somewhere else, you will have to modify the build files. How you do this, exactly, varies based on platform and what tools you have on hand. See <filename>README-Visual-C++.txt</filename>, <filename>README-MinGW.txt</filename>, or <filename>README-Mac-OS-X.txt</filename>, as appropriate.</para> </sect2> <sect2 id="max-fields"> <title>The Maximum Number of Fields Allowed</title> <para>MySQL++ offers two ways to automatically build SQL queries at run time: <xref linkend="tquery"/> and <link linkend="ssqls">SSQLS</link>. There’s a limit on the number of fields these mechanisms support, defaulting to 25 fields in the official MySQL++ packages.<footnote><para>If you’re using a third-party MySQL++ package, its maintainer may have increased these field counts so the resulting headers more closely approach the size limit of the compiler the package was built with. In that case, you can look at the top of each generated header file to find out how many fields each supports.</para></footnote> The files embodying these limits are <filename>lib/querydef.h</filename> and <filename>lib/ssqls.h</filename>, each generated by Perl scripts of the same name but with a <filename>.pl</filename> extension.</para> <para>The default <filename>querydef.h</filename> is small and its size only increases linearly with respect to maximum field count.</para> <para><filename>ssqls.h</filename> is a totally different story. The default 25 field limit makes <filename>ssqls.pl</filename> generate an <filename>ssqls.h</filename> over 1 MB. Worse, the field limit to file size relation is <emphasis>quadratic</emphasis>.<footnote><para>The file size equation, for you amateur mathematicians out there, is <phrase role="math">N<subscript>lines</subscript> = 18.5f<superscript>2</superscript> + 454.5f + 196.4</phrase>, where <varname>f</varname> is the field count.</para></footnote> This has a number of bad effects:</para> <itemizedlist> <listitem> <para>Generating header files to support more fields than you actually require is a waste of space and bandwidth.</para> </listitem> <listitem> <para>Some compilers have arbitrary limits on the size of macros they’re able to parse. Exceeding these limits usually causes the compiler to misbehave badly, rather than fail gracefully.</para> </listitem> <listitem> <para>Because it increases the size of two key files used in building MySQL++ itself and programs built on it, it increases compile times significantly. One test I did here showed a tripling of compile time from quadrupling the field limit.</para> </listitem> <listitem> <para>More than 25 fields in a table is a good sign of a bad database design, most likely a denormalization problem.</para> </listitem> </itemizedlist> <para>The default limits try to mitigate against all of these factors while still being high enough to be useful with most DB designs.</para> <para>If you’re building MySQL++ from source on a platform that uses Autoconf, the easiest way to change these limits is at configuration time:</para> <screen> ./configure --with-field-limit=50</screen> <para>That causes the configuration script to pass the <command>-f</command> flag to the two Perl scripts named above, overriding the default of 25 fields. Obviously you need a Perl interpreter on the system for this to work, but Perl is usually installed by default on systems MySQL++ supports via Autoconf.</para> <para>On all other platforms, you’ll have to give the <command>-f</command> flag to these scripts yourself. This may require installing Perl and putting it in the command path first. Having done that, you can do something like this to raise the limits:</para> <screen> cd lib perl ssqls.pl -f 50 perl querydef.pl -f 50</screen> <para>Note the need to run these commands within the <filename>lib</filename> subdirectory of the MySQL++ source tree. (This is done for you automatically on systems where you are able to use the Autoconf method.)</para> </sect2> <sect2 id="buried-headers"> <title>Buried MySQL C API Headers</title> <para>It’s common these days on Unixy systems to install the MySQL C API headers in a <filename>mysql</filename> directory under some common <filename>include</filename> directory. If the C API headers are in <filename>/usr/include/mysql</filename>, we say they are “buried” underneath the system’s main include directory, <filename>/usr/include</filename>. Since the MySQL++ headers depend on these C API headers, it can be useful for MySQL++ to know this fact.</para> <para>When MySQL++ includes one of the C API headers, it normally does so in the obvious way:</para> <programlisting> #include <mysql.h> </programlisting> <para>But, if you define the <varname>MYSQLPP_MYSQL_HEADERS_BURIED</varname> macro, it switches to this style:</para> <programlisting> #include <mysql/mysql.h> </programlisting> <para>In common situations like the <filename>/usr/include/mysql</filename> one, this simplifies the include path options you pass to your compiler.</para> </sect2> <sect2 id="c99"> <title>Building MySQL++ on Systems Without Complete C99 Support</title> <para>MySQL++ uses the <ulink url="http://en.wikipedia.org/wiki/C_(programming_language)#C99">C99</ulink> header <filename>stdint.h</filename> for portable fixed-size integer typedefs where possible. The C99 extensions aren’t yet officially part of the C++ Standard, so there are still some C++ compilers that don’t offer this header. MySQL++ works around the lack of this header where it knows it needs to, but your platform might not be recognized, causing the build to break. If this happens, you can define the <varname>MYSQLPP_NO_STDINT_H</varname> macro to make MySQL++ use its best guess for suitable integer types instead of relying on <filename>stdint.h</filename>.</para> <para>MySQL++ also uses C99’s <type>long long</type> data type where available. MySQL++ has workarounds for platforms where this is known not to be available, but if you get errors in <filename>common.h</filename> about this type, you can define the macro <varname>MYSQLPP_NO_LONG_LONGS</varname> to make MySQL++ fall back to portable constructs.</para> </sect2> </sect1> |
Changes to doc/userman/fo.xsl.
︙ | ︙ | |||
40 41 42 43 44 45 46 47 | </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> | > > > > > > > > > > > > > > > > > > > > > > > > | 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 | </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Disable hyphenation. The hyphenation patterns aren't installed as part of FOP, and we don't want it anyway. --> <xsl:template name="set.flow.properties"> <xsl:attribute name="hyphenate">false</xsl:attribute> </xsl:template> <!-- Rag-right lines --> <xsl:attribute-set name="root.properties"> <xsl:attribute name="text-align">left</xsl:attribute> </xsl:attribute-set> <!-- Use a smaller font for code listings to increase the chances that they can fit on a single sheet, to reduce FOP complaints about being forced to split a listing across pages. --> <xsl:attribute-set name="monospace.verbatim.properties"> <xsl:attribute name="font-size">85%</xsl:attribute> </xsl:attribute-set> <!-- Turn on extensions in DocBook stylesheets which make it use code that FOP 0.9x likes better. Doesn't affect anything with the 1.69.1 stylesheets we're using on EL5, but is said to help with 1.72 at least. --> <xsl:param name="fop1.extensions" select="1"/> </xsl:stylesheet> |
Added doc/userman/fo2pdf.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #!/bin/bash AHCMD=/usr/XSLFormatterV42/run.sh FOPCMD=$(type -p fop) XEPCMD=/usr/local/xep/xep FOFILE=$1 PDFFILE=$2 if [ -n "$FOFILE" -a -r "$FOFILE" -a -n "$PDFFILE" ] then if [ -x "$XEPCMD" ] then echo Rendering $FOFILE to $PDFFILE with RenderX XEP... $XEPCMD -quiet -fo $FOFILE -pdf $PDFFILE elif [ -x "$AHCMD" ] then echo Rendering $FOFILE to $PDFFILE with Antenna House XSL Formatter... $AHCMD -silent -d $FOFILE -o $PDFFILE elif [ -x "$FOPCMD" ] then echo "Rendering $FOFILE to $PDFFILE with Apache FOP ($FOPCMD)..." $FOPCMD -q -fo $FOFILE $PDFFILE else echo 'Cannot find a working XSL-FO processor on your system! See' echo 'doc/usrman/README.txt for instructions on installing one.' echo exit 1 fi else if [ -n "$FOFILE" ] then echo "XSL-FO file $FOFILE does not exist." echo fi echo "usage: $0 fofile pdffile" echo echo ' Translates XSL-FO in fofile to PDF output in pdffile.' echo exit 1 fi |
Changes to doc/userman/html.xsl.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 | 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"/> | > > > > > > | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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"/> <!-- The DocBook stylesheets use ISO 8859-1 by default, even when the XML files are marked UTF-8. If you serve such files from a web server that advertises UTF-8 content, browsers display the page incorrectly, because they believe the web server. --> <xsl:output method="html" encoding="UTF-8" indent="no"/> <!-- 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 |
︙ | ︙ | |||
45 46 47 48 49 50 51 | <!-- 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"> | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <!-- 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> |
︙ | ︙ | |||
67 68 69 70 71 72 73 | <!-- 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"> | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | <!-- 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> |
︙ | ︙ |
Added doc/userman/incorporating.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="incorporating"> <title>Using MySQL++ in Your Own Project</title> <para>Up to now, this manual has only discussed MySQL++ in conjunction with the example programs that come with the library. This chapter covers the steps you need to take to incorporate MySQL++ into your own projects.</para> <para>The first thing you have to do is include <filename>mysql++.h</filename> in each module that uses MySQL++. In modules that use <link linkend="ssqls">SSQLS v1</link>, you also need to include <filename>ssqls.h</filename>.<footnote><para>MySQL++ has many header files, but the only one that isn’t intertwined with the rest is <filename>ssqls.h</filename>. <filename>mysql++.h</filename> brings in all of the others in the correct order. Some have tried to speed their build times by finding a subset of MySQL++ headers to include, but <filename>mysql++.h</filename> already does as much of this as is practical. MySQL++’s monolithic nature rules out finding a true subset of the library headers.</para></footnote></para> <para>At this point, your project probably still won’t compile, and it certainly won’t link. The remaining steps are dependent on the operating system and tools you are using. The rest of this chapter is broken up into several sections, one for each major platform type. You can skip over the sections for platforms you don’t use.</para> <sect2 id="inc-vstudio"> <title>Visual C++</title> <sect3 id="inc-vstudio-mfc"> <title>Using MySQL++ in an MFC Project</title> <para>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.</para> <para>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 same change to both configurations.)</para> <itemizedlist> <listitem><para>Append the following to C/C++ | General | Additional Include Directories: <filename>C:\Program Files\MySQL\MySQL Connector C 6.1\include, C:\mysql++\include</filename></para></listitem> <listitem><para>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)”.</para></listitem> <listitem> <para>For both Release and Debug builds, append the following to Linker | General | Additional Library Directories: <filename>C:\Program Files\MySQL\MySQL Connector C 6.1\lib, C:\mysql++\lib</filename></para> <para>Connector/C does include debug libraries, but you will probably not need to use them.</para> </listitem> <listitem> <para>Under Linker | Input add the following to “Additional Dependencies” for the Debug configuration: <filename>libmysql.lib wsock32.lib mysqlpp_d.lib</filename></para> <para>...and then for the Release configuration: <filename>libmysql.lib wsock32.lib mysqlpp.lib</filename></para> <para>This difference is because MySQL++’s Debug DLL and import library have a <filename>_d</filename> suffix so you can have both in the same directory without conflicts.</para> </listitem> </itemizedlist> <para>You may want to study <filename>examples\vstudio\mfc\mfc.vcproj</filename> to see this in action. Note that some of the paths will be different, because it can use relative paths for <filename>mysqlpp.dll</filename>.</para> </sect3> <sect3 id="inc-vstudio-wforms"> <title>Using MySQL++ in a Windows Forms C++/CLI Project</title> <para>Before you start work on getting MySQL++ working with your own program, you need to make some changes to the MySQL++ build settings. Open <filename>mysqlpp.sln</filename>, then right-click on the mysqlpp target and select Properties. Make the following changes for both the Debug and Release configurations:</para> <itemizedlist> <listitem><para>Under Configuration Properties | General, change “Common Language Runtime support” to the /clr setting.</para></listitem> <listitem><para>Under C/C++ | Code Generation, change “Enable C++ Exceptions” from “Yes (/EHsc)” to “Yes With SEH Exceptions (/EHa)”</para></listitem> </itemizedlist> <para>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++. This is why MySQL++’s Windows installer (<filename>install.hta</filename>) offers the option to install the CLR version into a separate directory; use it if you need both managed and unmanaged versions installed!</para> <para>For the same reason, you might give some thought about where you install <filename>mysqlpp.dll</filename> on your end user’s machines when distributing your program. My recommendation is to install it in the same directory as the <filename>.exe</filename> file that uses it, rather than installing into a system directory where it could conflict with a <filename>mysqlpp.dll</filename> built with different settings.</para> <para>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.</para> <para>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:</para> <itemizedlist> <listitem><para>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++.)</para></listitem> <listitem><para>For the Linker | Input settings, you don’t need <filename>wsock32.lib</filename>. The mere fact that you’re using .NET takes care of that dependency for you.</para></listitem> </itemizedlist> <para>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 <ulink url="http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx">the MSDN article on the /clr switch</ulink> for details.</para> <para>You may want to study <filename>examples\vstudio\wforms\wforms.vcproj</filename> to see all this in action. Note that some of the paths will be different, because it can use relative paths for <filename>mysqlpp_d.dll</filename> and <filename>mysqlpp.dll</filename>.</para> </sect3> </sect2> <sect2 id="inc-unix"> <title>Unixy Platforms: Linux, *BSD, OS X, Cygwin, Solaris...</title> <para>There are lots of ways to build programs on Unixy platforms. We’ll cover just the most generic way here, <filename>Makefile</filename>s. We’ll use a very simple example so it’s clear how to translate this to more sophisticated build systems such as GNU Autotools or Bakefile.</para> <para>“Hello, world!” for MySQL++ might look something like this:</para> <programlisting><xi:include href="hello.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>Here’s a <filename>Makefile</filename> for building that program:</para> <programlisting><xi:include href="Makefile.hello.posix" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>The <varname>*FLAGS</varname> lines are where all of the assumptions about file and path names are laid out. Probably at least one of these assumptions isn’t true for your system, and so will require changing.</para> <para>The trickiest line is the <varname>LDLIBS</varname> one. MySQL++ programs need to get built against both the MySQL and MySQL++ libraries, because MySQL++ is built on top of the MySQL C API library<footnote><para>The MySQL C API library is most commonly called <filename>libmysqlclient</filename> on Unixy systems, though it is also known as <ulink url="https://dev.mysql.com/downloads/connector/c/">Connector/C</ulink>.</para></footnote> If you’re building a threaded program, use <filename>-lmysqlclient_r</filename> instead of <filename>-lmysqlclient</filename> here. (See <xref linkend="threads"/> for more details on building thread-aware programs.)</para> <para>On some systems, the order of libraries in the <varname>LDLIBS</varname> line is important: these linkers collect symbols from right to left, so the rightmost library needs to be the most generic. In this example, MySQL++ depends on MySQL, so the MySQL C API library is rightmost.</para> <para>You might need to add more libraries to the <varname>LDLIBS</varname> line. <filename>-lnsl</filename>, <filename>-lz</filename> and <filename>-lm</filename> are common. If you study how MySQL++ itself gets built on your system, you can see what it uses, and emulate that.</para> <para>You may be wondering why we have used both <varname>LDLIBS</varname> and <varname>LDFLAGS</varname> here. Some <filename>Makefiles</filename> you have seen collect both types of flags in a single variable. That can work if the variable is used in the right place in the link command. However, this particular <filename>Makefile</filename> is made with GNU make in mind, and uses its standard rules implicitly. Those rules are designed to use these two variables separately like this. If you were writing your own compilation rules, you could write them in such a way that you didn’t have to do this.</para> <para>Beyond that, we have a pretty vanilla <filename>Makefile</filename>, thanks in large part to the fact that the default <filename>make</filename> rules are fine for such a simple program.</para> </sect2> <sect2 id="inc-osx"> <title>OS X</title> <sect3 id="inc-osx-makefile"> <title>Makefiles</title> <para>The <link linkend="inc-unix">generic <filename>Makefile</filename> instructions above</link> cover most of what you need to know about using Makefiles on OS X.</para> <para>One thing that may trip you up on OS X is that it uses an uncommon dynamic linkage system. The easiest way to cope with this is to link your executables with the compiler, rather than call <filename>ld</filename> directly.</para> <para>Another tricky bit on OS X is the concept of Universal binaries. See <filename>README-Mac-OS-X.txt</filename> for details on building a Universal version of the MySQL++ library, if you need one. By default, you only get a version tuned for the system type you build it on.</para> </sect3> <sect3 id="inc-osx-xcode"> <title>Xcode</title> <para>I have no information on how to incorporate MySQL++ in an Xcode project. Send a message to the MySQL++ mailing list if you can help out here.</para> </sect3> </sect2> <sect2 id="inc-mingw"> <title>MinGW</title> <sect3 id="inc-mingw-makefile"> <title>Makefiles</title> <para>The <link linkend="inc-unix">generic <filename>Makefile</filename> instructions above</link> apply to MinGW’s version of GNU <filename>make</filename> as well. You will have some differences due to the platform, so here’s the adjusted <filename>Makefile</filename>:</para> <programlisting><xi:include href="Makefile.hello.mingw" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>Note that I’ve used <command>del</command> instead of <command>rm</command> in the clean target. In the past, at least, MinGW <filename>make</filename> had some funny rules about whether commands in target rules would get run with <filename>sh.exe</filename> or with <filename>cmd.exe</filename>. I can’t currently get my installation of MinGW to do anything but use <filename>sh.exe</filename> by default, but that may be because I have Cygwin installed, which provides <filename>sh.exe</filename>. This explains the first line in the file, which overrides the default shell with <filename>cmd.exe</filename>, purely to get consistent behavior across platforms. If you knew all your platforms would have a better shell, you’d probably want to use that instead.</para> <para>Note the use of forward slashes in the path to the MySQL Connector/C development files. GNU <filename>make</filename> uses the backslash as an escape character, so you’d have to double them if you’re unwilling to use forward slashes.</para> </sect3> <sect3 id="inc-mingw-ide"> <title>Third-Party MinGW IDEs (Dev-C++, Code::Blocks...)</title> <para>I have no information on how to do this. We’ve received reports on the mailing list from people that have made it work, but no specifics on what all needs to be done. The <filename>Makefile</filename> discussion above should give you some hints.</para> </sect3> </sect2> <sect2 id="inc-eclipse"> <title>Eclipse</title> <para>As far as I can tell, the simplest way to build a C++ project with Eclipse is to set up a <filename>Makefile</filename> for it as described <link linkend="inc-unix">above</link>, then add an external run configuration for your local <filename>make</filename> tool. Get the project building from the command line with <filename>make</filename>, then go to Run | External Tools | Open External Tools Dialog and add a new launch configuration.</para> <para>For example, on my OS X system I use <filename>/usr/bin/gnumake</filename> for the program location and pick the project root with the Browse Workspace button to set the working directory.</para> </sect2> </sect1> |
Added doc/userman/intro.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 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="intro"> <title>Introduction</title> <para>MySQL++ is a powerful C++ wrapper for MySQL’s C API<footnote><para>The MySQL C API is also known as <ulink url="https://dev.mysql.com/downloads/connector/c/">Connector/C</ulink>.</para></footnote>. 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 id="history"> <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. All of Kevin’s releases had pre-1.0 version numbers.</para> <para>Then in 1999, <ulink url="http://www.mysql.com/">MySQL AB</ulink> took over development of the library. In the beginning, <ulink url="http://en.wikipedia.org/wiki/Monty_Widenius">Monty Widenius</ulink> himself did some of the work, but later gave it over to another MySQL employee, Sinisa Milivojevic. MySQL released versions 1.0 and 1.1, and then 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. It seems to be during this time that the dream of multiple-database compatibility died, for obvious reasons.</para> <para>With version 1.7.9, MySQL++ went into a period of stasis, lasting over three years. (Perhaps it was the ennui and retrenchment following the collapse of <ulink url="http://en.wikipedia.org/wiki/Dot-com_bubble">the bubble</ulink> that caused them to lose interest.) During this time, Sinisa ran the MySQL++ mailing list and supported its users, but made no new releases. Contributed patches were either ignored or put up on the MySQL++ web site for users to try, without any official blessing.</para> <para>The biggest barrier to using MySQL++ during this period is that the popular C++ compilers of 2001 weren’t all that compatible with the C++ Standard. As a result, MySQL++ used many nonstandard constructs, to allow for compatibility with older compilers. Each new compiler released in the following years increased compliance, either warning about or rejecting code using pre-Standard constructs. In particular, <ulink url="http://gcc.gnu.org/">GCC</ulink> was emerging from the mess following the <ulink url="http://en.wikipedia.org/wiki/GNU_Compiler_Collection#EGCS">EGCS fork</ulink> during this time. The fork was healed officially in 1999, but there’s always a delay of a few years between the release of a new GCC and widespread adoption. The post-EGCS versions of GCC were only beginning to become popular by 2001, when development on MySQL++ halted. As a result, it became increasingly difficult to get MySQL++ to build cleanly as newer compilers came out. Since MySQL++ uses templates heavily, this affected end user programs as well: MySQL++ code got included directly in your program, so any warnings or errors it caused became your program’s problem.</para> <para>As a result, most of the patches contributed to the MySQL++ project during this period were to fix up standards compliance issues. Because no one was bothering to officially test and bless these patches, you ended up with the worst aspects of a <ulink url="http://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar">bazaar</ulink> development model: complete freedom of development, but no guiding hand to select from the good stuff and reject the rest. Many of the patches were mutually incompatible. Some would build upon other patches, so you had to apply them in the proper sequence. Others did useful things, but didn’t give a fully functional copy of MySQL++. Figuring out which patch(es) to use was an increasingly frustrating exercise as the years wore on, and newer GCCs became popular.</para> <para>In early August of 2004, Warren Young got fed up with this situation and took over. He released 1.7.10 later that month, which did little more than make the code build with GCC 3.3 without warnings. Since then, with a little help from his friends on the Net, MySQL++ has lost a lot of bugs, gained a lot of features, gained a few more bugs, lost them again... MySQL++ is alive and healthy now.</para> </sect2> <sect2 id="asking-questions"> <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> |
Added doc/userman/licenses.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <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 — excepting some example code from the library reproduced within it — 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 id="lgpl"> <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 id="lgpl-preamble"> <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 id="lgpl-terms"> <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 id="lgpl-howto"> <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><one line to give the library’s name and a brief idea of what it does.></para> <para>Copyright © <year> <name of author></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><signature of Ty Coon>, 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 id="userman-license"> <title>MySQL++ User Manual License</title> <sect3 id="userman-license-copyright"> <title>I. COPYRIGHT</title> <para>The copyright to the MySQL++ User Manual is owned by its authors.</para> </sect3> <sect3 id="userman-license-main"> <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 id="userman-license-req"> <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> |
Changes to doc/userman/mktxt.
1 2 3 4 5 6 | #!/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. | > > > > | > | | | | 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 |
Added doc/userman/overview.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="overview"> <title>Overview</title> <para>MySQL++ has a lot of complexity and power to cope with the variety of ways people use databases, but at bottom it doesn’t work all that differently than other database access APIs. The usage pattern looks like this:</para> <orderedlist> <listitem><para>Open the connection</para></listitem> <listitem><para>Form and execute the query</para></listitem> <listitem><para>If successful, iterate through the result set</para></listitem> <listitem><para>Else, deal with errors</para></listitem> </orderedlist> <para>Each of these steps corresponds to a MySQL++ class or class hierarchy. An overview of each follows.</para> <sect2 id="Connection"> <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> <para>MySQL supports many different types of data connection between the client and the server: TCP/IP, Unix domain sockets, and Windows named pipes. The generic <classname>Connection</classname> class supports all of these, figuring out which one you mean based on the parameters you pass to <methodname>Connection::connect()</methodname>. But if you know in advance that your program only needs one particular connection type, there are subclasses with simpler interfaces. For example, there’s <ulink type="classref" url="TCPConnection"/> if you know your program will always use a networked database server.</para> </sect2> <sect2 id="Query"> <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> acts as a standard C++ output stream, so you can write data to it like you would to <classname>std::cout</classname> or <classname>std::ostringstream</classname>. This is the most C++ish way MySQL++ provides for building up a query string. The library includes <ulink url="../refman/manip_8h.html">stream manipulators</ulink> that are type-aware so it’s easy to build up syntactically-correct SQL.</para> <para><classname>Query</classname> also has a feature called <xref linkend="tquery"/> which 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 <link linkend="ssqls">SSQLS</link>. This feature lets you create C++ structures that mirror your database schemas. These in turn give <classname>Query</classname> the information it needs to build many common SQL queries for you. It can <command>INSERT</command>, <command>REPLACE</command> and <command>UPDATE</command> rows in a table given the data in SSQLS form. It can also generate <command>SELECT * FROM SomeTable</command> queries and store the results as an STL collection of SSQLSes.</para> </sect2> <sect2 id="Result"> <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="String"/>. 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 <command>DATETIME</command> 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 id="SimpleResult"> <title>Queries That Do Not Return Data</title> <para>Not all SQL queries return data. An example is <command>CREATE TABLE</command>. For these types of queries, there is a special result type (<ulink type="classref" url="SimpleResult"/>) 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 id="StoreQueryResult"> <title>Queries That Return Data: MySQL++ Data Structures</title> <para>The most direct way to retrieve a result set is to use <methodname>Query::store()</methodname>. This returns a <ulink type="classref" url="StoreQueryResult"/> object, which derives from <classname>std::vector<mysqlpp::Row></classname>, making it a random-access container of <ulink type="classref" url="Row"/>s. In turn, each <classname>Row</classname> object is like a <classname>std::vector</classname> of <classname>String</classname> objects, one for each field in the result set. Therefore, you can treat <classname>StoreQueryResult</classname> as a two-dimensional array: you can get the 5th field on the 2nd row by simply saying <methodname>result[1][4]</methodname>. You can also access row elements by field name, like this: <methodname>result[2]["price"]</methodname>.</para> <para>A less direct way of working with query results is to use <methodname>Query::use()</methodname>, which returns a <ulink type="classref" url="UseQueryResult"/> object. This class acts like an STL input iterator rather than a <classname>std::vector</classname>: you walk through your result set processing one row 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. In payment for that inconvenience, you get better memory efficiency, because the entire result set doesn’t need to be stored in RAM. This is very useful when you need large result sets.</para> </sect3> <sect3 id="storein"> <title>Queries That Return Data: Specialized SQL Structures</title> <para>Accessing results through MySQL++’s data structures is a pretty low level of abstraction. It’s better than using the MySQL C API, but not by much. You can elevate things a little closer to the level of the problem space by using the <link linkend="ssqls">SSQLS feature</link>. This lets you define C++ structures that match the table structures in your database schema. In addition, it’s easy to use SSQLSes with regular STL containers (and thus, algorithms) so you don’t have to deal with the quirks of MySQL++’s data structures.</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 an STL container — sequential or set-associative, it doesn’t matter — for you. Consider this:</para> <programlisting> vector<stock> v; query << "SELECT * FROM stock"; query.storein(v); for (vector<stock>::iterator it = v.begin(); it != v.end(); ++it) { cout << "Price: " << it->price << endl; }</programlisting> <para>Isn’t that slick?</para> <para>If you don’t want to create SSQLSes to match your table structures, as of MySQL++ v3 you can now use <classname>Row</classname> here instead:</para> <programlisting> vector<mysqlpp::Row> v; query << "SELECT * FROM stock"; query.storein(v); for (vector<mysqlpp::Row>::iterator it = v.begin(); it != v.end(); ++it) { cout << "Price: " << it->at("price") << endl; }</programlisting> <para>It lacks a certain syntactic elegance, but it has its uses.</para> </sect3> </sect2> <sect2 id="exceptions-intro"> <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> |
Added doc/userman/section-template.dbx.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="SOMETHING_UNIQUE"> <title>SECTION TITLE</title> <para>FIRST PARAGRAPH</para> </sect1> |
Added doc/userman/ssqls.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="ssqls"> <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. At the most superficial level, an SSQLS has a member variable corresponding to each field in the SQL table. But, an SSQLS also has several methods, operators, and data members used by MySQL++’s internals to provide neat functionality, which we cover in this chapter.</para> <para>You define SSQLSes using the macros defined in <filename>ssqls.h</filename>. This is the only MySQL++ header not automatically included for you by <filename>mysql++.h</filename>. You have to include it in code modules that use the SSQLS feature.</para> <sect2 id="sql_create"> <title>sql_create</title> <para>Let’s say you have the following SQL table:</para> <programlisting> CREATE TABLE stock ( item CHAR(30) NOT NULL, num BIGINT NOT NULL, weight DOUBLE NOT NULL, price DECIMAL(6,2) NOT NULL, sdate DATE NOT NULL, description MEDIUMTEXT NULL)</programlisting> <para>You can create a C++ structure corresponding to this table like so:</para> <programlisting> sql_create_6(stock, 1, 6, mysqlpp::sql_char, item, mysqlpp::sql_bigint, num, mysqlpp::sql_double, weight, mysqlpp::sql_decimal, price, mysqlpp::sql_date, sdate, mysqlpp::Null<mysqlpp::sql_mediumtext>, description)</programlisting> <para>This declares the <classname>stock</classname> structure, which has a data member for each SQL column, using the same names. The structure also has a number of member functions, operators and hidden data members, but we won’t go into that just now.</para> <para>The parameter before each field name in the <function>sql_create_#</function> call is the C++ data type that will be used to hold that value in the SSQLS. While you could use plain old C++ data types for most of these columns (<type>long int</type> instead of <type>mysqlpp::sql_bigint</type>, for example) it’s <link linkend="sql-types">best to use the MySQL++ typedefs</link>.</para> <para>Sometimes you have no choice but to use special MySQL++ data types to fully express the database schema. Consider the <varname>description</varname> field. MySQL++’s <type>sql_mediumtext</type> type is just an alias for <type>std::string</type>, since we don’t need anything fancier to hold a SQL <type>MEDIUMTEXT</type> value. It’s the SQL NULL attribute that causes trouble: it <link linkend="sql-null">has no equivalent in the C++ type system</link>. MySQL++ offers the <ulink type="classref" url="Null"/> template, which bridges this difference between the two type systems.</para> <para>The general format of this macro 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 id="ssqls-compare-init"> <title>SSQLS Comparison and Initialization</title> <para>The <varname>sql_create_#</varname> macro 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 SSQLS 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> 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<stock> result; query.storein(result); cout << result.lower_bound(stock("Hamburger"))->item << 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> 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_6(stock, 1, 2, mysqlpp::sql_char, item, mysqlpp::sql_bigint, num, mysqlpp::sql_double, weight, mysqlpp::sql_decimal, price, mysqlpp::sql_date, sdate, mysqlpp::Null<mysqlpp::sql_mediumtext>, description) 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++. You might be asking, why does there need to be a constructor for comparison to begin with? 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.</para> <para>This limitation is not a problem in practice. If you want the same number of parameters in the initialization constructor as the number of fields used in comparisons, pass 0 for <parameter>SETCOUNT</parameter>. This suppresses the duplicate constructor you’d get if you used the <parameter>COMPCOUNT</parameter> value instead. This is most useful in very small SSQLSes, since it’s easier for the number of key fields to equal the number of fields you want to compare on:</para> <programlisting> sql_create_1(stock_item, 1, 0, mysqlpp::sql_char, item)</programlisting> </sect2> <sect2 id="ssqls-retrieving"> <title>Retrieving data</title> <para>Let’s put SSQLS to use. This is <filename>examples/ssqls1.cpp</filename>:</para> <programlisting><xi:include href="ssqls1.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>Here is the stock.h header used by that example, and by several others below:</para> <programlisting><xi:include href="stock.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>This example produces the same output as <filename>simple1.cpp</filename> (see <xref linkend="simple"/>), but it uses higher-level data structures paralleling the database schema instead of MySQL++’s lower-level generic data structures. It also uses MySQL++’s <xref linkend="exceptions"/> for error handling instead of doing everything inline. For small example programs like these, the overhead of SSQLS and exceptions doesn’t pay off very well, but in a real program, they end up working much better than hand-rolled code.</para> <para>Notice that we are only pulling a single column from the <varname>stock</varname> table, but we are storing the rows in a <type>std::vector<stock></type>. It may strike you as inefficient to have five unused fields per record. It’s easily remedied by defining a subset SSQLS:</para> <programlisting> sql_create_1(stock_subset, 1, 0, string, item) vector<stock_subset> res; query.storein(res); // ...etc...</programlisting> <para>MySQL++ is flexible about populating SSQLSes.<footnote><para>Programs built against versions of MySQL++ prior to 3.0 would crash at almost any mismatch between the database schema and the SSQLS definition. It’s no longer necessary to keep the data design in lock-step between the client and database server. A mismatch can result in data loss, but not a crash.</para></footnote> It works much like the Web, a design that’s enabled the development of the largest distributed system in the world. Just as a browser ignores tags and attributes it doesn’t understand, you can populate an SSQLS from a query result set containing columns that don’t exist in the SSQLS. And as a browser uses sensible defaults when the page doesn’t give explicit values, you can have an SSQLS with more fields defined than are in the query result set, and these SSQLS fields will get default values. (Zero for numeric types, <type>false</type> for <type>bool</type>, and a type-specific default for anything more complex, like <type>mysqlpp::DateTime</type>.)</para> <para>In more concrete terms, the example above is able to populate the <classname>stock</classname> objects using as much information as it has, and leave the remaining fields at their defaults. Conversely, you could also stuff the results of <computeroutput>SELECT * FROM stock</computeroutput> into the <classname>stock_subset</classname> SSQLS declared above; the extra fields would just be ignored.</para> <para>We’re trading run-time efficiency for flexibility here, usually the right thing in a distributed system. Since MySQL is a networked database server, many uses of it will qualify as distributed systems. You can’t count on being able to update both the server(s) and all the clients at the same time, so you have to make them flexible enough to cope with differences while the changes propagate. As long as the new database schema isn’t too grossly different from the old, your programs should continue to run until you get around to updating them to use the new schema.</para> <para>There’s a danger that this quiet coping behavior may mask problems, but considering that the previous behavior was for the program to crash when the database schema got out of synch with the SSQLS definition, it’s likely to be taken as an improvement.</para> </sect2> <sect2 id="ssqls-adding"> <title>Adding data</title> <para>MySQL++ offers several ways to insert data in SSQLS form into a database table.</para> <sect3 id="ssqls-add-one"> <title>Inserting a Single Row</title> <para>The simplest option is to insert a single row at a time. This is <filename>examples/ssqls2.cpp</filename>:</para> <programlisting><xi:include href="ssqls2.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>That’s all there is to it! MySQL++ even takes care of <link linkend="qescape">quoting and escaping</link> the data when building queries from SSQLS structures. It’s efficient, too: MySQL++ is smart enough to quote and escape data only for those data types that actually require it.</para> </sect3> <sect3 id="ssqls-add-range"> <title>Inserting Many Rows</title> <para>Inserting a single row is useful, to be sure, but you might want to be able to insert many SSQLSes or <classname>Row</classname> objects at once. MySQL++ knows how to do that, too, sparing you the necessity of writing the loop. Plus, MySQL++ uses an optimized implementation of this algorithm, packing everything into a single SQL query, eliminating the overhead of multiple calls between the client and server. It’s just a different overload of <methodname>insert()</methodname>, which accepts a pair of iterators into an STL container, inserting every row in that range:</para> <programlisting>vector<stock> lots_of_stuff; ...populate the vector somehow... query.insert(lots_of_stuff.begin(), lots_of_stuff.end()).execute();</programlisting> <para>By the way, notice that you can chain <classname>Query</classname> operations like in the last line above, because its methods return <symbol>*this</symbol> where that makes sense.</para> </sect3> <sect3 id="ssqls-insertfrom"> <title>Working Around MySQL’s Packet Size Limit</title> <para>The two-iterator form of <methodname>insert()</methodname> has an associated risk: MySQL has a limit on the size of the SQL query it will process. The default limit is 1 MB. You can raise the limit, but the reason the limit is configurable is not to allow huge numbers of inserts in a single query. They made the limit configurable because a single row might be bigger than 1 MB, so the default would prevent you from inserting anything at all. If you raise the limit simply to be able to insert more rows at once, you’re courting disaster with no compensating benefit: the more data you send at a time, the greater the chance and cost of something going wrong. Worse, this is pure risk, because by the time you hit 1 MB, the per-packet overhead is such a small fraction of the data being transferred that increasing the packet size buys you essentially nothing.</para> <para>Let’s say you have a <classname>vector</classname> containing several megabytes of data; it will get even bigger when expressed in SQL form, so there’s no way you can insert it all in a single query without raising the MySQL packet limit. One way to cope would be to write your own naïve loop, inserting just one row at a time. This is slow, because you’re paying the per-query cost for every row in the container. Then you might realize that you could use the two iterator form of <methodname>insert()</methodname>, passing iterators expressing sub-ranges of the container instead of trying to insert the whole container in one go. Now you’ve just got to figure out how to calculate those sub-ranges to get efficient operation without exceeding the packet size limit.</para> <para>MySQL++ already knows how to do that, too, with <methodname>Query::insertfrom()</methodname>. We gave it a different name instead of adding yet another <methodname>insert()</methodname> overload because it doesn’t merely build the <command>INSERT</command> query, which you then <methodname>execute()</methodname>. It’s more like <methodname>storein()</methodname>, in that it wraps the entire operation up in a single call. This feature is demonstrated in <filename>examples/ssqls6.cpp</filename>:</para> <programlisting><xi:include href="ssqls6.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>Most of the complexity in this example goes to just reading in the data from a file; we have to get our test data from somewhere. There are only two key lines of code: create an insertion policy object, and pass it along with an STL container full of row data to <methodname>Query::insertfrom()</methodname>.</para> <para>This policy object is the main thing that differentiates <methodname>insertfrom()</methodname> from the two-iterator form of <methodname>insert()</methodname>. It controls how <methodname>insertfrom()</methodname> builds the query strings, primarily controlling how large each query gets before <methodname>insertfrom()</methodname> executes it and starts building a new query. We designed it to use policy objects because there is no single “right” choice for the decisions it makes.</para> <para>MySQL++ ships with three different insertion policy classes, which should cover most situations.</para> <para><classname>MaxPacketInsertPolicy</classname>, demonstrated in the example above, does things the most obvious way: when you create it, you pass the maximum packet size, which it uses to prevent queries from going over the size limit. It builds up a query string row by row, checking each time through the loop whether adding another insert statement to the query string would make the packet size go over the limit. When that happens, or it gets to the end of the iteration range, it executes the query and starts over if it’s not yet at the end. This is robust, but it has a downside: it has to build each insert query in advance of knowing that it can append it to the larger query. Any time an insert query would push the packet over the limit, it has to throw it away, causing the library to do more work than is strictly necessary.</para> <para>Imagine you’ve done some benchmarking and have found that the point of diminishing returns is at about 20 KB per query in your environment; beyond that point, the per-query overhead ceases to be an issue. Let’s also say you know for a fact that your largest row will always be less than 1 MB — less 20 KB — when expressed as a SQL insert statement. In that case, you can use the more efficient <classname>SizeThresholdInsertPolicy</classname>. It differs from <classname>MaxPacketInsertPolicy</classname> in that it allows <methodname>insertfrom()</methodname> to insert rows blindly into the query string until the built query exceeds the threshold, 20 KB in this example. Then it ships the packet off, and if successful, starts a new query. Thus, each query (except possibly the last) will be at least 20 KB, exceeding that only by as much as one row’s worth of data, minus one byte. This is quite appropriate behavior when your rows are relatively small, as is typical for tables not containing BLOB data. It is more efficient than <classname>MaxPacketInsertPolicy</classname> because it never has to throw away any SQL fragments.</para> <para>The simplest policy object type is <classname>RowCountInsertPolicy</classname>. This lets you simply say how many rows at a time to insert into the database. This works well when you have a good handle on how big each row will be, so you can calculate in advance how many rows you can insert at once without exceeding some given limit. Say you know your rows can’t be any bigger than about 1 KB. If we stick with that 20 KB target, passing <classname>RowCountInsertPolicy<>(20)</classname> for the policy object would ensure we never exceed the size threshold. Or, say that maximum size value above is still true, but we also know the average row size is only 200 bytes. You could pass <classname>RowCountInsertPolicy<>(100)</classname> for the policy, knowing that the average packet size will be around 20 KB, and the worst case packet size 100 KB, still nowhere near the default 1 MB packet size limit. The code for this policy is very simple, so it makes your program a little smaller than if you used either of the above policies. Obviously it’s a bad choice if you aren’t able to predict the size of your rows accurately.</para> <para>If one of the provided insert policy classes doesn’t suit your needs, you can easily create a custom one. Just study the implementation in <filename>lib/insertpolicy.*</filename>.</para> </sect3> <sect3 id="ssqls-insertfrom-transactions"> <title>Interaction with Transactions</title> <para>These policy classes are all templates, taking a parameter that defaults to <ulink type="classref" url="Transaction"/>. This means that, by default, <methodname>insertfrom()</methodname> wraps the entire operation in a SQL transaction, so that if any of the insertions fail, the database server rolls them all back. This prevents an error in the middle of the operation from leaving just part of the container’s data inserted in the database, which you usually don’t want any more than you’d want half a single row to be inserted.</para> <para>There are good reasons why you might not want this. Perhaps the best reason is if the <methodname>insertfrom()</methodname> call is to be part of a larger transaction. MySQL doesn’t support nested transactions, so the <methodname>insertfrom()</methodname> call will fail if it tries to start one of its own. You can pass <classname>NoTransactions</classname> for the insert policy’s template parameter to make it suppress the transaction code.</para> </sect3> </sect2> <sect2 id="ssqls-modifying"> <title>Modifying data</title> <para>It almost as easy to modify data with SSQLS as to add it. This is <filename>examples/ssqls3.cpp</filename>:</para> <programlisting><xi:include href="ssqls3.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>Don’t forget to run <filename>resetdb</filename> after running the example.</para> </sect2> <sect2 id="ssqls-comparing"> <title>Storing SSQLSes in Associative Containers</title> <para>One of the requirements of STL’s associative containers on data stored in them is that the data type has to be less-than comparable. That is, it has to have an <function>operator <</function> defined. SSQLS does optionally give you this, as demonstrated in <filename>examples/ssqls4.cpp</filename>:</para> <programlisting><xi:include href="ssqls4.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>The <methodname>find()</methodname> call works because of the way the SSQLS was declared. It’s properly covered <link linkend="ssqls-compare-init">elsewhere</link>, but suffice it to say, the “1” in the declaration of <classname>stock</classname> <link linkend="ssqls-retrieving">above</link> tells it that only the first field needs to be checked in comparing two SSQLSes. In database terms, this makes it the primary key. Therefore, when searching for a match, our exemplar only had to have its first field populated.</para> </sect2> <sect2 id="ssqls-table-name"> <title>Changing the Table Name</title> <para>Another feature you might find a use for is changing the table name MySQL++ uses to build queries involving SSQLSes. By default, the database server table 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> <para>It’s also possible to change the name of a table on a per-instance basis:</para> <programlisting> stock s; s.instance_table("AlternateTable");</programlisting> <para>This is useful when you have an SSQLS definition that is compatible with multiple tables, so the table name to use for each instance is different. This feature saves you from having to define a separate SSQLS for each table. It is also useful for mapping a class hierarchy onto a set of table definitions. The common SSQLS definition is the “superclass” for a given set of tables.</para> <para>Strictly speaking, you only need to use this feature in multithreaded programs. Changing the static table name before using each instance is safe if all changes happen within a single thread. That said, it may still be convenient to change the name of the table for an SSQLS instance in a single-threaded program if it gets used for many operations over an extended span of code.</para> </sect2> <sect2 id="ssqls-in-header"> <title>Using an SSQLS in Multiple Modules</title> <para>It’s convenient to define an SSQLS in a header file so you can use it in multiple modules. You run into a bit of a problem, though, because each SSQLS includes a few static data members to hold information common to all structures of that type. (The table name and the list of field names.) When you <command>#include</command> that header in more than one module, you get a multiply-defined symbol error at link time.</para> <para>The way around this is to define the preprocessor macro <varname>MYSQLPP_SSQLS_NO_STATICS</varname> in <emphasis>all but one</emphasis> of the modules that use the header definining the SSQLS. When this macro is defined, it suppresses the static data members in any SSQLS defined thereafter.</para> <para>Imagine we have a file <filename>my_ssqls.h</filename> which includes a <function>sql_create_N</function> macro call to define an SSQLS, and that that SSQLS is used in at least two modules. One we’ll call <filename>foo.cpp</filename>, and we’ll say it’s just a user of the SSQLS; it doesn’t “own” it. Another of the modules, <filename>my_ssqls.cpp</filename> uses the SSQLS more heavily, so we’ve called it the owner of the SSQLS. If there aren’t very many modules, this works nicely:</para> <programlisting> // File foo.cpp, which just uses the SSQLS, but doesn’t "own" it: #define MYSQLPP_SSQLS_NO_STATICS #include "my_ssqls.h"</programlisting> <programlisting> // File my_ssqls.cpp, which owns the SSQLS, so we just #include it directly #include "my_ssqls.h"</programlisting> <para>If there are many modules that need the SSQLS, adding all those <command>#defines</command> can be a pain. In that case, it’s easier if you flip the above pattern on its head:</para> <programlisting> // File my_ssqls.h: #if !defined(EXPAND_MY_SSQLS_STATICS) # define MYSQLPP_SSQLS_NO_STATICS #endif sql_create_X(Y, Z....) // the SSQLS definition</programlisting> <programlisting> // File foo.cpp, a mere user of the SSQLS: #include "my_ssqls.h"</programlisting> <programlisting> // File my_ssqls.cpp, which owns the SSQLS: #define EXPAND_MY_SSQLS_STATICS #include "my_ssqls.h"</programlisting> </sect2> <sect2 id="ssqls-internals"> <title>Harnessing SSQLS Internals</title> <para>The <symbol>sql_create</symbol> macros define several methods 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>ssqls*.cpp</filename> examples:</para> <programlisting> // Basic form template <class Manip> stock_value_list<Manip> value_list(cchar *d = ",", Manip m = mysqlpp::quote) const; template <class Manip> stock_field_list<Manip> field_list(cchar *d = ",", Manip m = mysqlpp::do_nothing) const; template <class Manip> stock_equal_list<Manip> equal_list(cchar *d = ",", cchar *e = " = ", Manip m = mysqlpp::quote) const; // Boolean argument form template <class Manip> stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,] ] bool i1, bool i2 = false, ... , bool i5 = false) const; // List form template <class Manip> stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,] ] stock_enum i1, stock_enum i2 = stock_NULL, ..., stock_enum i5 = stock_NULL) const; // Vector form template <class Manip> stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,] ] vector<bool> *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, sql_date("1998-05-25")); cout << "Value list: " << s.value_list() << endl; cout << "Field list: " << s.field_list() << endl; cout << "Equal list: " << s.equal_list() << 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,sdate Equal list: item = 'Dinner Rolls’,num = 75,weight = 0.95, price = 0.97,sdate = '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 << "INSERT INTO " << v.table() << " (" << v.field_list() << ") VALUES (" << v.value_list() << ")";</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/ssqls5.cpp</filename>:</para> <programlisting><xi:include href="ssqls5.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> 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 << "select * from stock where " << 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<bool> v(5, false); v[stock_weight] = true; v[stock_price] = true; query << "select * from stock where " << 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 id="ssqls-field-names"> <title>Having Different Field Names in C++ and SQL</title> <para>There’s a more advanced SSQLS creation macro, which all the others are built on top of. Currently, the only feature it adds over what’s described above is that it lets you name your SSQLS fields differently from the names used by the database server. Perhaps you want to use <ulink url="http://en.wikipedia.org/wiki/Hungarian_notation">Hungarian notation</ulink> in your C++ program without changing the SQL database schema:</para> <programlisting> sql_create_complete_5(stock, 1, 5, mysqlpp::sql_char, m_sItem, "item", mysqlpp::sql_bigint, m_nNum, "num", mysqlpp::sql_double, m_fWeight, "weight", mysqlpp::sql_decimal, m_fPrice, "price", mysqlpp::sql_date, m_Date, "sdate")</programlisting> <para>Note that you don’t have to use this mechanism if the only difference in your SQL and C++ field names is case. SSQLS field name lookups are case-insensitive as of MySQL++ 3.1. You can see this in the examples: some parts of the code deliberately refer to the <classname>stock.sdate</classname> sample table field as <classname>stock.sDate</classname> to exercise this feature.</para> </sect2> <sect2 id="ssqls-pretty"> <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 < 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 the <command>-I</command> flag at the top of the script.</para> </sect2> <sect2 id="ssqls-customization"> <title>Customizing the SSQLS Mechanism</title> <para>The SSQLS header <filename>ssqls.h</filename> is automatically generated by the Perl script <filename>ssqls.pl</filename>. Although it is possible to change this script to get additional functionality, most of the time it’s better to just derive a custom class from the generated SSQLS to add functionality to it. (See the <link linkend="ssqls-derivation">next section</link> to see how to do this correctly.)</para> <para>That said, <filename>ssqls.pl</filename> does have a few configurables you might want to tweak.</para> <para>The first configurable value sets the maximum number of data members allowed in an SSQLS. This is discussed elsewhere, in <xref linkend="max-fields"/>. Beware the warnings there about increasing this value too much.</para> <para>The second configurable is the default floating point precision used for comparison. As described above (<xref linkend="ssqls-compare-init"/>) SSQLSes can be compared for equality. The only place this is tricky is with floating-point numbers, since rounding errors can make two “equal” values compare as distinct. This property of floating-point numbers means we almost never want to do exact comparison. MySQL++ lets you specify the precision you want it to use. If the difference between two values is under a given threshold, MySQL++ considers the values equal. The default threshold is 0.00001. This threshold works well for “human” scale values, but because of the way floating-point numbers work, it can be wildly inappropriate for very large or very small quantities like those used in scientific applications.</para> <para>There are actually two ways to change this threshold. If you need a different system-wide default, edit <filename>ssqls.pl</filename> and change the <varname>$fp_min_delta</varname> variable at the top of the file, then rebuild <filename>ssqls.h</filename> as described below. If you need different thresholds per file or per project, it’s better to set the C macro <varname>MYSQLPP_FP_MIN_DELTA</varname> instead. The Perl variable sets this macro’s default; if you give a different value before #including <filename>ssqls.h</filename>, it will use that instead.</para> <para>To rebuild <filename>ssqls.h</filename> after changing <filename>ssqls.pl</filename>, you’ll need a Perl interpreter. The only modern Unixy system I’m aware of where Perl isn’t installed by default is Cygwin, and it’s just a <filename>setup.exe</filename> choice away there. You’ll probably only have to download and install a Perl interpreter if you’re on Windows and don’t want to use Cygwin.</para> <para>If you’re on a system that uses autoconf, building MySQL++ automatically updates <filename>ssqls.h</filename> any time <filename>ssqls.pl</filename> changes. Otherwise, you’ll need to run the Perl interpreter by hand:</para> <screen>c:\mysql++> cd lib c:\lib> perl ssqls.pl</screen> </sect2> <sect2 id="ssqls-derivation"> <title>Deriving from an SSQLS</title> <para>Specialized SQL Structures make good base classes. They’re simple, and have few requirements on any class that derives from them. There are some gotchas to look out for, however.</para> <para>Consider this:</para> <programlisting> sql_create_2( Base, 1, 2, mysqlpp::sql_varchar, a, mysqlpp::sql_int, b ); class Derived : public Base { public: // constructor Derived(mysqlpp::sql_varchar _a, mysqlpp::sql_int _b) : Base(_a, _b) { } // functionality added to the SSQLS through inheritance bool do_something_interesting(int data); };</programlisting> <para>We’ve derived a class from an SSQLS in order to add a method to it. Easy, right?</para> <para>Sadly, too easy. The code has a rather large flaw which makes our derived class unusable as an SSQLS. In C++, if a derived class has a function of the same name as one in the base class, the base class versions of that function are all hidden by those in the derived class. This applies to constructors, too: an SSQLS defines several constructors, but our derived class defines only one, causing that one to hide all of the ones in the base class. Many of the MySQL++ mechanisms that use SSQLSes rely on having these contructors, so our <classname>Derived</classname> above is-not-a <classname>Base</classname>, and so it isn’t an SSQLS. If you try to use <classname>Derived</classname> as an SSQLS, you’ll get compiler errors wherever MySQL++ tries to access one of these other constructors.</para> <para>There’s another minor flaw, as well. Our lone constructor above takes its parameters by value, but the corresponding constructor in the SSQLS takes them by const reference. Our derived class has technically hidden a fourth base class constructor this way, but this particular case is more a matter of efficiency than correctness. Code that needs the full-creation constructor will still work with our code above, but passing stringish types like <classname>sql_varchar</classname> by value instead of by const reference is inefficient.</para> <para>This is the corrected version of the above code:</para> <programlisting> sql_create_2( Base, 1, 2, mysqlpp::sql_varchar, a, mysqlpp::sql_int, b ); class Derived : public Base { public: // default constructor<footnote><para>needed by mechanisms like <methodname>Query::storein()</methodname>; anything using an STL container, which usually require default ctors for contained data structures</para></footnote> Derived() : Base() { } // for-comparison constructor<footnote><para>takes the <parameter>COMPCOUNT</parameter> subset of the SSQLS’s data members, used for making comparison exemplars, used with <methodname>Query::update()</methodname> and similar mechanisms; see <xref linkend="sql_create"/> for more on <parameter>COMPCOUNT</parameter></para></footnote> Derived(const mysqlpp::sql_varchar& _a) : Base(_a) { } // full creation constructor Derived(const mysqlpp::sql_varchar& _a, const mysqlpp::sql_int& _b) : Base(_a, _b) { } // population constructor<footnote><para>used in taking raw row data from a SQL result set and converting it to SSQLS form</para></footnote> Derived(const mysqlpp::Row& row) : Base(row) { } // functionality added to the SSQLS through inheritance bool do_something_interesting(int data); };</programlisting> <para>Now <classname>Derived</classname> is-an SSQLS.</para> <para>You might wonder if you can use protected inheritance above to redefine the SSQLS’s public interface. For instance, OO purists might object to the public data members in an SSQLS. You could encapsulate these public data members in the derived class by using protected inheritance, exposing access to the base class’s data members with public accessor methods. The problem with this is that each SSQLS has <emphasis>dozens</emphasis> of public member functions. These are needed by MySQL++ internals, so unless you re-exposed all of them as we did with the constructors above, you’d again have an SSQLS derivative that is-not-an SSQLS. Simply put, only public inheritance is practical with SSQLSes.</para> </sect2> <sect2 id="ssqls-blob"> <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="String">String</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>String</classname> object’s contents, without interference.</para> <para>Because 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>String</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>String</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>String</classname> ensures that your code tracks these library changes automatically. Besides, <classname>String</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 avoiding that looming redesign effort.</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> <sect2 id="ssqls-vc2003"> <title>SSQLS and Visual C++ 2003</title> <para>SSQLS works on all platforms supported by MySQL++ except for Visual C++ 2003. (Because the rest of MySQL++ works just fine with Visual C++ 2003, we haven’t removed this platform from the supported list entirely.)</para> <para>If you do need SSQLS and are currently on Visual C++ 2003, you have these options:</para> <orderedlist> <listitem><para>The simplest option is to upgrade to a newer version of Visual C++. The compiler limitations that break SSQLS are all fixed in Visual C++ 2005 and newer. <ulink url="http://www.microsoft.com/express/vc/">Visual C++ Express</ulink> is free and is apparently here to stay; coupled with the free <ulink url="http://wxwidgets.org/">wxWidgets</ulink> library, it lacks little compared to Visual C++ Professional. A bonus of using wxWidgets is that it’s cross-platform and better-supported than MFC.</para></listitem> <listitem><para>If you can’t upgrade your compiler, you may be able to downgrade to MySQL++ v2.<emphasis>x</emphasis>. The SSQLS feature in these older versions worked with Visual C++ 2003, but didn’t let you use a given SSQLS in more than one module in a program. If you can live with that limitation and have a Perl interpreter on your system, you can re-generate <filename>lib/ssqls.h</filename> to remove the multiple-module SSQLS support. To do this, you run the command <command>perl ssqls.pl -v</command> from within MySQL++’s <filename>lib</filename> subdirectory before you build and install the library.</para></listitem> <listitem><para>There’s <ulink url="http://svn.gna.org/viewcvs/*checkout*/mysqlpp/trunk/Wishlist">a plan</ulink> to replace the current SSQLS mechanism with an entirely new code base. Although this is being done primarily to get new features that are too difficult to add within the current design, it also means we’ll have the chance to test step-by-step along the way that we don’t reintroduce code that Visual C++ 2003 doesn’t support. This may happen without you doing anything, but if there’s someone on the team who cares about this, that will naturally increase the chances that it does happen.</para></listitem> </orderedlist> </sect2> </sect1> |
Added doc/userman/threads.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="threads"> <title>Using MySQL++ in a Multithreaded Program</title> <para>MySQL++ is not “thread safe” in any meaningful sense. MySQL++ contains very little code that actively prevents trouble with threads, and all of it is optional. We have done some work in MySQL++ to make thread safety <emphasis>achievable</emphasis>, but it doesn’t come for free.</para> <para>The main reason for this is that MySQL++ is generally I/O-bound, not processor-bound. That is, if your program’s bottleneck is MySQL++, the ultimate cause is usually the I/O overhead of using a client-server database. Doubling the number of threads will just let your program get back to waiting for I/O twice as fast. Since <ulink url="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf">threads are evil</ulink> and generally can’t help MySQL++, the only optional thread awareness features we turn on in the shipping version of MySQL++ are those few that have no practical negative consequences. Everything else is up to you, the programmer, to evaluate and enable as and when you need it.</para> <para>We’re going to assume that you are reading this chapter because you find yourself needing to use threads for some other reason than to speed up MySQL access. Our purpose here is limited to setting down the rules for avoiding problems with MySQL++ in a multi-threaded program. We won’t go into the broader issues of thread safety outside the scope of MySQL++. You will need a grounding in threads in general to get the full value of this advice.</para> <sect2 id="thread-build"> <title>Build Issues</title> <para>Before you can safely use MySQL++ with threads, there are several things you must do to get a thread-aware build:</para> <orderedlist> <listitem> <para><emphasis>Build MySQL++ itself with thread awareness turned on.</emphasis></para> <para>On Linux, Cygwin and Unix (OS X, *BSD, Solaris...), pass the <computeroutput>--enable-thread-check</computeroutput> flag to the <filename>configure</filename> script. Beware, this is only a request to the <filename>configure</filename> script to look for thread support on your system, not a requirement to do or die: if the script doesn’t find what it needs to do threading, MySQL++ will just get built without thread support. See <filename>README-Unix.txt</filename> for more details.</para> <para>On Windows, if you use the Visual C++ project files or the MinGW Makefile that comes with the MySQL++ distribution, threading is always turned on, due to the nature of Windows.</para> <para>If you build MySQL++ in some other way, such as with Dev-Cpp (based on MinGW) you’re on your own to enable thread awareness.</para> </listitem> <listitem> <para><emphasis>Link your program to a thread-aware build of the MySQL C API library.</emphasis></para> <para>If you use a binary distribution of MySQL on Unixy systems (including Cygwin) you usually get two different versions of the MySQL C API library, one with thread support and one without. These are typically called <filename>libmysqlclient</filename> and <filename>libmysqlclient_r</filename>, the latter being the thread-safe one. (The “<filename>_r</filename>” means reentrant.)</para> <para>If you’re using the Windows binary distribution of MySQL, you should have only one version of the C API library, which should be thread-aware. If you have two, you probably just have separate debug and optimized builds. See <filename>README-Visual-C++.txt</filename> or <filename>README-MinGW.txt</filename> for details.</para> <para>If you build MySQL from source, you might only get one version of the MySQL C API library, and it can have thread awareness or not, depending on your configuration choices.</para> </listitem> <listitem> <para><emphasis>Enable threading in your program’s build options.</emphasis></para> <para>This is different for every platform, but it’s usually the case that you don’t get thread-aware builds by default. Depending on the platform, you might need to change compiler options, linker options, or both. See your development environment’s documentation, or study how MySQL++ itself turns on thread-aware build options when requested.</para> </listitem> </orderedlist> </sect2> <sect2 id="thread-conn-mgmt"> <title>Connection Management</title> <para>The MySQL C API underpinning MySQL++ does not allow multiple concurrent queries on a single connection. You can run into this problem in a single-threaded program, too, which is why we cover the details elsewhere, in <xref linkend="concurrentqueries"/>. It’s a thornier problem when using threads, though.</para> <para>The simple fix is to just create a separarate <ulink url="Connection" type="classref"/> object for each thread that needs to make database queries. This works well if you have a small number of threads that need to make queries, and each thread uses its connection often enough that the server doesn’t <link linkend="conn-timeout">time out</link> waiting for queries.</para> <para>If you have lots of threads or the frequency of queries is low, the connection management overhead will be excessive. To avoid that, we created the <ulink url="ConnectionPool" type="classref"/> class. It manages a pool of <classname>Connection</classname> objects like library books: a thread checks one out, uses it, and then returns it to the pool as soon as it’s done with it. This keeps the number of active connections low. We suggest that you keep each connection’s use limited to a single variable scope for <ulink url="http://en.wikipedia.org/wiki/RAII">RAII</ulink> reasons; we created a little helper called <ulink url="ScopedConnection" type="classref"/> to make that easy.</para> <para><classname>ConnectionPool</classname> has three methods that you need to override in a subclass to make it concrete: <methodname>create()</methodname>, <methodname>destroy()</methodname>, and <methodname>max_idle_time()</methodname>. These overrides let the base class delegate operations it can’t successfully do itself to its subclass. The <classname>ConnectionPool</classname> can’t know how to <methodname>create()</methodname> the <classname>Connection</classname> objects, because that depends on how your program gets login parameters, server information, etc. <classname>ConnectionPool</classname> also makes the subclass <methodname>destroy()</methodname> the <classname>Connection</classname> objects it created; it could assume that they’re simply allocated on the heap with <methodname>new</methodname>, but it can’t be sure, so the base class delegates destruction, too. Finally, the base class can’t know which connection idle timeout policy would make the most sense to the client, so it asks its subclass via the <methodname>max_idle_time()</methodname> method.</para> <para><classname>ConnectionPool</classname> also allows you to override <methodname>release()</methodname>, if needed. For simple uses, it’s not necessary to override this.</para> <para>In designing your <classname>ConnectionPool</classname> derivative, you might consider making it a <ulink url="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton</ulink>, since there should only be one pool in a program.</para> <para>Another thing you might consider doing is passing a <ulink url="ReconnectOption" type="classref"/> object to <methodname>Connection::set_option()</methodname> in your <methodname>create()</methodname> override before returning the new <classname>Connection</classname> pointer. This will cause the underlying MySQL C API to try to reconnect to the database server if a query fails because the connection was dropped by the server. This can happen if the DB server is allowed to restart out from under your application. In many applications, this isn’t allowed, or if it does happen, you might want your code to be able to detect it, so MySQL++ doesn’t set this option for you automatically.</para> <para>Here is an example showing how to use connection pools with threads:</para> <programlisting><xi:include href="cpool.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>The example works with both Windows native threads and with POSIX threads.<footnote><para>The file <filename>examples/threads.h</filename> contains a few macros and such to abstract away the differences between the two threading models.</para></footnote> Because thread-enabled builds are only the default on Windows, it’s quite possible for this program to do nothing on other platforms. See above for instructions on enabling a thread-aware build.</para> <para>If you write your code without checks for thread support like you see in the code above and link it to a build of MySQL++ that isn’t thread-aware, it will still try to run. The threading mechanisms fall back to a single-threaded mode when threads aren’t available. A particular danger is that the mutex lock mechanism used to keep the pool’s internal data consistent while multiple threads access it will just quietly become a no-op if MySQL++ is built without thread support. We do it this way because we don’t want to make thread support a MySQL++ prerequisite. And, although it would be of limited value, this lets you use <classname>ConnectionPool</classname> in single-threaded programs.</para> <para>You might wonder why we don’t just work around this weakness in the C API transparently in MySQL++ instead of suggesting design guidelines to avoid it. We’d like to do just that, but how?</para> <para>If you consider just the threaded case, you could argue for the use of mutexes to protect a connection from trying to execute two queries at once. The cure is worse than the disease: it turns a design error into a performance sap, as the second thread is blocked indefinitely waiting for the connection to free up. Much better to let the program get the “Commands out of sync” error, which will guide you to this section of the manual, which tells you how to avoid the error with a better design.</para> <para>Another option would be to bury <classname>ConnectionPool</classname> functionality within MySQL++ itself, so the library could create new connections at need. That’s no good because the above example is the most complex in MySQL++, so if it were mandatory to use connection pools, the whole library would be that much more complex to use. The whole point of MySQL++ is to make using the database easier. MySQL++ offers the connection pool mechanism for those that really need it, but an option it must remain.</para> </sect2> <sect2 id="thread-helpers"> <title>Helper Functions</title> <para><classname>Connection</classname> has several thread-related static methods you might care about when using MySQL++ with threads.</para> <para>You can call <methodname>Connection::thread_aware()</methodname> to determine whether MySQL++ and the underlying C API library were both built to be thread-aware. I want to stress that thread <emphasis>awareness</emphasis> is not the same thing as thread <emphasis>safety</emphasis>: it’s still up to you to make your code thread-safe. If this method returns true, it just means it’s <emphasis>possible</emphasis> to achieve thread-safety, not that you actually have it.</para> <para>If your program’s connection-management strategy allows a thread to use a <classname>Connection</classname> object that another thread created, you need to know about <methodname>Connection::thread_start()</methodname>. This function sets up per-thread resources needed to make MySQL server calls. You don’t need to call it when you use the simple <classname>Connection</classname>-per-thread strategy, because this function is implicitly called the first time you create a <classname>Connection</classname> in a thread. It’s not harmful to call this function from a thread that previously created a <classname>Connection</classname>, just unnecessary. The only time it’s necessary is when a thread can make calls to the database server on a <classname>Connection</classname> that another thread created and that thread hasn’t already created a <classname>Connection</classname> itself.</para> <para>If you use <classname>ConnectionPool</classname>, you should call <methodname>thread_start()</methodname> at the start of each worker thread because you probably can’t reliably predict whether your <methodname>grab()</methodname> call will create a new <classname>Connection</classname> or will return one previously returned to the pool from another thread. It’s possible to conceive of situations where you can guarantee that each pool user always creates a fresh <classname>Connection</classname> the first time it calls <methodname>grab()</methodname>, but thread programming is complex enough that it’s best to take the safe path and always call <methodname>thread_start()</methodname> early in each worker thread.</para> <para>Finally, there’s the complementary method, <methodname>Connection::thread_end()</methodname>. Strictly speaking, it’s not <emphasis>necessary</emphasis> to call this. The per-thread memory allocated by the C API is small, it doesn’t grow over time, and a typical thread is going to need this memory for its entire run time. Memory debuggers aren’t smart enough to know all this, though, so they will gripe about a memory leak unless you call this from each thread that uses MySQL++ before that thread exits.</para> <para>Although its name suggests otherwise, <methodname>Connection::thread_id()</methodname> has nothing to do with anything in this chapter.</para> </sect2> <sect2 id="thread-data-sharing"> <title>Sharing MySQL++ Data Structures</title> <para>We’re in the process of making it safer to share MySQL++’s data structures across threads. Although things are getting better, it’s highly doubtful that all problems with this are now fixed. By way of illustration, allow me explain one aspect of this problem and how we solved it in MySQL++ 3.0.0.</para> <para>When you issue a database query that returns rows, you also get information about the columns in each row. Since the column information is the same for each row in the result set, older versions of MySQL++ kept this information in the result set object, and each <ulink url="Row" type="classref"/> kept a pointer back to the result set object that created it so it could access this common data at need. This was fine as long as each result set object outlived the <classname>Row</classname> objects it returned. It required uncommon usage patterns to run into trouble in this area in a single-threaded program, but in a multi-threaded program it was easy. For example, there’s frequently a desire to let one connection do the queries, and other threads process the results. You can see how avoiding lifetime problems here would require a careful locking strategy.</para> <para>We got around this in MySQL++ v3.0 by giving these shared data structures a lifetime independent of the result set object that intitially creates it. These shared data structures stick around until the last object needing them gets destroyed.</para> <para>Although this is now a solved problem, I bring it up because there are likely other similar lifetime and sequencing problems waiting to be discovered inside MySQL++. If you would like to help us find these, by all means, share data between threads willy-nilly. We welcome your crash reports on the MySQL++ mailing list. But if you’d prefer to avoid problems, it’s better to keep all data about a query within a single thread. Between this and the advice in prior sections, you should be able to use threads with MySQL++ without trouble.</para> </sect2> </sect1> |
Added doc/userman/tquery.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <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/tquery1.cpp</filename>:</para> <programlisting><xi:include href="tquery1.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 id="tquery-setup"> <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 << "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 escape the item using the MySQL C API function <ulink url="mysql-escape-string" type="mysqlapi"/> and add single quotes around it as necessary, depending on the type of the value you use.</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> </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 id="tquery-parms"> <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 &parm0, [..., const SQLString &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> StoreQueryResult 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 id="tquery-defaults"> <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::template_defaults</varname> array. You can refer to the parameters either by position or by name:</para> <programlisting> query.template_defaults[1] = "item"; query.template_defaults["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.template_defaults["field1"] = "item"; query.template_defaults["field2"] = "price"; StoreQueryResult res1 = query.store("Hamburger Buns", "item"); StoreQueryResult 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.template_defaults["what"] = "Hamburger Buns"; query.template_defaults["wheref"] = "item"; query.template_defaults["field1"] = "item"; query.template_defaults["field2"] = "price"; StoreQueryResult 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 id="tquery-errors"> <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::template_defaults</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.template_defaults["field1"] = "item"; query.template_defaults["field2"] = "price"; StoreQueryResult 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> |
Added doc/userman/tutorial.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="tutorial" xreflabel="Tutorial"> <title>Tutorial</title> <para>The <link linkend="overview">previous chapter</link> introduced the major top-level mechanisms in MySQL++. Now we’ll dig down a little deeper and get into real examples. We start off with the basics that every MySQL++ program will have to deal with, then work up to more complex topics that are still widely interesting. You can stop reading the manual after this chapter and still get a lot out of MySQL++, ignoring the more advanced parts we present in later chapters.</para> <sect2 id="examples"> <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 use RPMs instead, the example programs’ source code and a simplified <filename>Makefile</filename> are in the <filename>mysql++-devel</filename> package. They are typically installed in <filename>/usr/share/doc/mysql++-devel-*/examples</filename>, but it can vary on different Linuxes.</para> <para>Before you get started, please read through any of the <filename>README*.txt</filename> 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 can run it like so:</para> <screen>resetdb [-s server_addr] [-u user] [-p password]</screen> <para>Actually, there’s a problem with that. It assumes that the MySQL++ library is already installed in a directory that the operating system’s dynamic linker can find. (MySQL++ is almost never built statically.) Unless you’re installing from RPMs, you’ve had to build the library from source, and you should run at least a few of the examples before installing the library to be sure it’s working correctly. Since your operating system’s dynamic linkage system can’t find the MySQL++ libraries without help until they’re installed, we’ve created a few helper scripts to help run the examples.</para> <para>MySQL++ comes with the <filename>exrun</filename> shell script for Unixy systems, and the <filename>exrun.bat</filename> batch file for Windows. You pass the example program and its arguments to the <filename>exrun</filename> helper, which sets up the library search path so that it will use the as-yet uninstalled version of the MySQL++ library in preference to any other on your system:</para> <screen>./exrun resetdb [-s server_addr] [-u user] [-p password]</screen> <para>That’s the typical form for a Unixy system. You leave off the <command>./</command> bit on Windows. You can leave it off on a Unixy system, too, if you have <filename>.</filename> in your <varname>PATH</varname>. (Not a recommendation, just an observation.)</para> <para>All of the program arguments are optional.</para> <para>If you don’t give <option>-s</option>, the underlying MySQL C API (a.k.a. <ulink url="https://dev.mysql.com/downloads/connector/c/">Connector/C</ulink>) assumes the server is on the local machine. It chooses one of several different IPC options based on the platform configuration. There are many different forms you can give as <varname>server_addr</varname> with <option>-s</option> to override this default behavior:</para> <itemizedlist> <listitem> <para><emphasis>localhost</emphasis> — this is the default; it doesn’t buy you anything</para> </listitem> <listitem> <para>On Windows, a simple period tells the underlying MySQL C API to use named pipes, if it’s available.</para> </listitem> <listitem> <para><emphasis>172.20.0.252:12345</emphasis> — this would connect to IP address <computeroutput>172.20.0.252</computeroutput> on TCP port <computeroutput>12345</computeroutput>.</para> </listitem> <listitem> <para><emphasis>my.server.name:svc_name</emphasis> — this would first look up TCP service name <computeroutput>svc_name</computeroutput> in your system’s network services database (<filename>/etc/services</filename> on Unixy systems, and something like <filename>c:\windows\system32\drivers\etc\services</filename> on modern Windows variants). If it finds an entry for the service, it then tries to connect to that port on the domain name given.</para> </listitem> </itemizedlist> <para>For the TCP forms, you can mix names and numbers for the host and port/service parts in any combination. If the server name doesn’t contain a colon, it uses the default port, 3306.</para> <para>If you don’t give <option>-u</option>, it assumes your user name on the database server is the same as your login name on the local machine.</para> <para>If you don’t give <option>-p</option>, it will assume the MySQL user doesn’t have a password. (One hopes this isn’t the case...)</para> <para>When running <filename>resetdb</filename>, the user name needs to be for an account with permission to create the test database. Once the database is created, you can use any account when running the other examples that has DELETE, INSERT, SELECT and UPDATE permissions for the test database. The MySQL root user can do all this, of course, but you might want to set up a separate user, having only the permissions necessary to work with the test database:</para> <screen> CREATE USER mysqlpp_test@'%' IDENTIFIED BY ’nunyabinness'; GRANT ALL PRIVILEGES ON mysql_cpp_data.* TO mysqlpp_test@'%';</screen> <para>You could then create the sample database with the following command:</para> <screen>./exrun resetdb -u mysqlpp_test -p nunyabinness</screen> <para>(Again, leave off the <command>./</command> bit on Windows.)</para> <para>You may have to re-run <filename>resetdb</filename> after running some of the other examples, as they change the database.</para> <para>See <filename>README-examples.txt</filename> for more details on running the examples.</para> </sect2> <sect2 id="simple"> <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="StoreQueryResult"/> derives from <classname>std::vector</classname>, and <ulink type="classref" url="Row"/> provides an interface that makes it a <classname>vector</classname> work-alike. This means you can access elements with subscript notation, walk through them with iterators, run STL algorithms on them, etc.</para> <para><classname>Row</classname> provides a little more in this area than a plain old <classname>vector</classname>: you can also access fields by name using subscript notation.</para> <para>The only thing that isn’t explicit in the code above is that we delegate command line argument parsing to <function>parse_command_line()</function> in the <filename>excommon</filename> module. This function exists to give the examples a consistent interface, not to hide important details. You can treat it like a black box: it takes <varname>argc</varname> and <varname>argv</varname> as inputs and sends back database connection parameters.</para> </sect2> <sect2 id="simple2"> <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. We’ve been suppressing this in all the examples so far by passing <symbol>false</symbol> to <classname>Connection</classname>’s constructor. This kept these early examples simple at the cost of some flexibility and power in error handling. In a real program, we recommend that you leave exceptions enabled. You do this by either using the default <classname>Connection</classname> constructor, or by using the create-and-connect constructor.</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>. 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>When exceptions are suppressed, MySQL++ signals errors by returning either an error code or an object that tests as false, or by setting an error flag on the object. Classes that allow you to suppress exceptions derive from the <ulink type="classref" url="OptionalExceptions"/> interface. When an <classname>OptionalExceptions</classname> derivative 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. This is why passing <symbol>false</symbol> for the <classname>Connection</classname> constructor’s “throw exceptions” parameter suppresses all optional exceptions in the <filename>simple[1-3]</filename> examples. It keeps them, well, simple.</para> <para>This exception suppression mechanism is quite granular. It’s possible to leave exceptions enabled most of the time, but suppress them in sections of the code where they aren’t helpful. 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:</para> <programlisting>mysqlpp::Connection con; // default ctor, so exceptions enabled { mysqlpp::NoExceptions ne(con); if (!con.select_db("a_db_that_might_not_exist_yet")) { // Our DB doesn’t exist yet, so create and select it here; no need // to push handling of this case way off in an exception handler. } }</programlisting> <para>When one <classname>OptionalExceptions</classname> derivative passes its exceptions flag to another such object, it is only passing a copy; 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 disabled optional exceptions.</para> <para>MySQL++ throws some exceptions unconditionally:</para> <itemizedlist> <listitem><para>MySQL++ checks array indices, always. For instance, if your code said “<varname>row[21]</varname>” on a row containing only 5 fields, you’d get a <classname>BadIndex</classname> exception. If you say “<varname>row["fred"]</varname>” on a row without a “fred” field, you get a <classname>BadFieldName</classname> exception. In the past, MySQL++ delegated some of its index checking to the STL containers underpinning it, so you could get <classname>std::range_error</classname> instead. As of MySQL++ v3.0.7, this should no longer happen, but there may be instances where it still does.</para></listitem> <listitem><para><ulink type="classref" url="String"/> 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 use a C++ data type in a query that MySQL++ doesn’t know to convert to SQL, MySQL++ will throw a <ulink type="classref" url="TypeLookupFailed"/> exception. It typically happens with <xref linkend="ssqls"/>, especially when using data types other than the ones defined in <filename>lib/sql_types.h</filename>.</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>String</classname> conversion error.</para> </sect2> <sect2 id="qescape" xreflabel="quoting and escaping"> <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 << "SELECT * FROM stock WHERE item = " << quote_only << 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 any type of data that can be converted to MySQL++’s <ulink type="classref" url="SQLTypeAdapter">SQLTypeAdapter</ulink> type, plus the <ulink type="classref" url="Set"/> template. <link linkend="ssqls">SSQLS</link> also uses these manipulators internally.</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 << "SELECT * FROM stock WHERE item = " << quote << s; </programlisting> <para>The <type>quote</type> manipulator both quotes strings and escapes any characters that are special in SQL.</para> <para>MySQL++ provides other manipulators as well. See the <ulink url="../refman/manip_8h.html">manip.h</ulink> page in the <ulink url="../refman/index.html">reference manual</ulink>.</para> <para>It’s important to realize that MySQL++’s quoting and escaping mechanism is type-aware. Manipulators have no effect unless you insert the manipulator into a <classname>Query</classname> or <ulink type="classref" url="SQLQueryParms">SQLQueryParms</ulink> stream. <footnote><para><classname>SQLQueryParms</classname> is used as a stream only as an implementation detail within the library. End user code simply sees it as a <classname>std::vector</classname> derivative.</para></footnote> Also, values are only quoted and/or escaped if they are of a data type that may need it. For example, <ulink type="structref" url="Date">Date</ulink> must be quoted but never needs to be escaped, and integer types need neither quoting nor escaping. Manipulators are suggestions to the library, not commands: MySQL++ will ignore these suggestions if it knows it won’t result in syntactically-incorrect SQL.</para> <para>It’s also important to realize that quoting and escaping in <classname>Query</classname> streams and template queries is never implicit.<footnote><para>By contrast, the <classname>Query</classname> methods that take an <link linkend="ssqls">SSQLS</link> <emphasis>do</emphasis> add quotes and escape strings implicitly. It can do this because SSQLS knows all the SQL code and data types, so it never has to guess whether quoting or escaping is appropriate.</para></footnote> You must use manipulators and template query flags as necessary to tell MySQL++ where quoting and escaping is necessary. It would be nice if MySQL++ could do quoting and escaping implicitly based on data type, but this isn’t possible in all cases.<footnote id="whyexpmanip"><para>Unless you’re smarter than I am, you don’t immediately see why explicit manipulators are necessary. We can tell when quoting and escaping is <emphasis>not</emphasis> appropriate based on type, so doesn’t that mean we know when it <emphasis>is</emphasis> appropriate? Alas, no. For most data types, it is possible to know, or at least make an awfully good guess, but it’s a complete toss-up for C strings, <type>const char*</type>. A C string could be either a literal string of SQL code, or it can be a value used in a query. Since there’s no easy way to know and it would damage the library’s usability to mandate that C strings only be used for one purpose or the other, the library requires you to be explicit.</para></footnote> Since MySQL++ can’t reliably guess when quoting and escaping is appropriate, and the programmer doesn’t need to<footnote><para>One hopes the programmer <emphasis>knows</emphasis>.</para></footnote>, MySQL++ makes you tell it.</para> </sect2> <sect2 id="sql-types"> <title>C++ vs. SQL Data Types</title> <para>The C++ and SQL data type systems have several differences that can cause problems when using MySQL++, or any other SQL based system, for that matter.</para> <para>Most of the data types you can store in a SQL database are either numbers or text strings. If you’re only looking at the data going between the database server and your application, there aren’t even numbers: SQL is a textual language, so numbers and everything else gets transferred between the client and the database server in text string form.<footnote><para>Yes, we’re aware that there is a feature in MySQL that lets you transfer row data in a binary form, but we don’t support this yet. We may, someday, probably as an extension to <link linkend="ssqls">SSQLS</link>. The only real reason to do so is to shave off some of the data translation overhead, which is typically neglibible in practice, swamped by the far greater disk and network I/O overheads inherent in use of a client-server database system like MySQL.</para></footnote> Consequently, MySQL++ has a lot of <link linkend="string-types">special support</link> for text strings, and can translate to several C++ numeric data types transparently.</para> <para>Some people worry that this translation via an intermediate string form will cause data loss. Obviously the text string data types are immune from problems in this regard. We’re also confident that MySQL++ translates <link linkend="blob">BLOB</link> and integer data types losslessly.</para> <para>The biggest worry is with floating-point numbers. (The FLOAT and DOUBLE SQL data types.) We did have a problem with this in older versions of MySQL++, but we believe we fixed it completely in v3.0.2. No one has since proven data loss via this path. There is still a known problem <footnote> <para>SQL’s DECIMAL data type is a configurable-precision fixed-point number format. MySQL++ currently translates these to <type>double</type>, a floating-point data format, the closest thing available in the C++ type system. Since the main reason to use DECIMAL is to get away from the weird roundoff behavior of floating-point numbers, this could be viewed as a serious problem. The thing is, though, in all the years MySQL++ has been around, I don’t remember anyone actually complaining about it. Apparently there’s either no one using DECIMAL with MySQL++, or they’re ignoring any roundoff errors they get as a result. Until this wheel squeaks, it’s not likely to be greased. To fix this, we’ll have to create a new custom data type to hold such column values, which will be a lot of work for apparently little return.</para> </footnote> with the SQL DECIMAL type, which is somewhat related to the floating-point issue, but it’s apparently rarely encountered, which is why it hasn’t been fixed yet.</para> <para>The best way to avoid problems with data translation is to always use the special MySQL++ data types defined in <filename>lib/sql_types.h</filename> corresponding to your SQL schema. These typedefs begin with <type>sql_</type> and end with a lowercase version of the standard SQL type name, with spaces replaced by underscores. There are variants ending in <type>_null</type> that wrap these base types so they’re <link linkend="sql-null">compatible with SQL null</link>. For instance, the SQL type <type>TINYINT UNSIGNED NOT NULL</type> is represented in MySQL++ by <classname>mysqlpp::sql_tinyint_unsigned</classname>. If you drop the <type>NOT NULL</type> part, the corresponding C++ type is <classname>mysqlpp::sql_tinyint_unsigned_null</classname>.</para> <para>MySQL++ doesn’t force you to use these typedefs. It tries to be flexible with regard to data conversions, so you could probably use <type>int</type> anywhere you use <classname>mysqlpp::sql_tinyint_unsigned</classname>, for example. That said, the MySQL++ typedefs give several advantages:</para> <itemizedlist> <listitem><para>Space efficiency: the MySQL++ types are no larger than necessary to hold the MySQL data.</para></listitem> <listitem><para>Portability: if your program has to run on multiple different system types (even just 32- and 64-bit versions of the same operating system and processor type) using the MySQL++ typedefs insulates your code from platform changes.</para></listitem> <listitem><para>Clarity: using C++ types named similarly to the SQL types reduces the risk of confusion when working with code in both languages at the same time.</para></listitem> <listitem><para>Compatibility: using the MySQL++ types ensures that data conversions between SQL and C++ forms are compatible. Naïve use of plain old C++ types can result in data truncation, <ulink type="classref" url="TypeLookupFailed"/> exceptions, and worse.</para> <para>Type compatibility is important not just at the time you write your program, it also helps forward compatibility: we occasionally change the definitions of the MySQL++ typedefs to reduce the differences between the C++ and SQL type systems. We’ll be fixing the DECIMAL issue brought up above this way, for instance; if your program uses <classname>sql_decimal</classname> instead of the current underlying type, <type>double</type>, your program will pick up this improvement automatically with just a recompile.</para></listitem> </itemizedlist> <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> <para>MySQL++ doesn’t have typedefs for the most exotic data types, like those for the geospatial types. Patches to correct this will be thoughtfully considered.</para> </sect2> <sect2 id="sql-null"> <title>Handling SQL Nulls</title> <para>Both C++ and SQL have things in them called NULL, but they differ in several ways. Consequently, MySQL++ has to provide special support for this, rather than just wrap native C++ facilities as it can with most data type issues.</para> <sect3 id="sql-null-type"> <title>SQL NULL is a type modifier</title> <para>The primary distinction is one of type. In SQL, “NULL” is a type modifier, which affects whether you can legally store a null value in that column. There’s simply nothing like it in C++.</para> <para>To emulate SQL NULL, 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>TINYINT UNSIGNED</type> column that can have nulls, the proper declaration for MySQL++ would be:</para> <programlisting> mysqlpp::Null<mysqlpp::sql_tinyint_unsigned> myfield;</programlisting> <para>As of MySQL++ 3.1, we also provide shorter aliases for such types:</para> <programlisting> mysqlpp::sql_tinyint_unsigned_null myfield;</programlisting> <para>These types are declared in <filename>lib/sql_types.h</filename>. You might want to scan through that to see what all is available.</para> <para>Template instantiations are first-class types in the C++ language, so there’s no possible confusion between this feature of MySQL++ and C++’s native NULL concept.</para> </sect3> <sect3 id="sql-null-value"> <title>SQL NULL is a unique value</title> <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>If you insert a MySQL++ field holding a SQL null into a C++ IOstream, you get “(NULL)”, something fairly unlikely to be in a normal output string, thus reasonably preserving the uniqueness of the SQL null value.</para> <para>MySQL++ also tries to enforce the uniqueness of the SQL null value at compile time in assignments and data conversions. If you try to store a SQL null in a field type that isn’t wrapped by <classname>Null</classname> or try to assign a <classname>Null</classname>-wrapped field value to a variable of the inner non-wrapped type, the compiler will emit some ugly error message, yelling about <type>CannotConvertNullToAnyOtherDataType</type>. (The exact message is compiler-dependent.)</para> <para>If you don’t like these behaviors, you can change them 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 SQL null. To relax the distinctions, 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<unsigned char, mysqlpp::NullIsZero> myfield(mysqlpp::null); cout << myfield << endl; cout << int(myfield) << 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 wouldn’t even compile.</para> </sect3> </sect2> <sect2 id="string-types"> <title>MySQL++’s Special String Types</title> <para>MySQL++ has two classes that work like <classname>std::string</classname> to some degree: <ulink type="classref" url="String"/> and <ulink type="classref" url="SQLTypeAdapter"/>. These classes exist to provide functionality that <classname>std::string</classname> doesn’t provide, but they are neither derivatives of nor complete supersets of <classname>std::string</classname>. As a result, end-user code generally doesn’t deal with these classes directly, because <classname>std::string</classname> is a better general-purpose string type. In fact, MySQL++ itself uses <classname>std::string</classname> most of the time, too. But, the places these specialized stringish types do get used are so important to the way MySQL++ works that it’s well worth taking the time to understand them.</para> <sect3 id="SQLTypeAdapter"> <title>SQLTypeAdapter</title> <para>The simpler of the two is <classname>SQLTypeAdapter</classname>, or <classname>STA</classname> for short.<footnote><para>In version 2 of MySQL++ and earlier, <classname>SQLTypeAdapter</classname> was called <classname>SQLString</classname>, but it was confusing because its name and the fact that it derived from <classname>std::string</classname> suggested that it was a general-purpose string type. MySQL++ even used it this way in a few places internally. In v3, we made it a simple base class and renamed it to reflect its proper limited function.</para></footnote></para> <para>As its name suggests, its only purpose is to adapt other data types to be used with SQL. It has a whole bunch of conversion constructors, one for all data types we expect to be used with MySQL++ for values in queries. SQL queries are strings, so constructors that take stringish types just make a copy of that string, and all the others “stringize” the value in the format needed by SQL.<footnote><para><classname>SQLTypeAdapter</classname> doesn’t do <xref linkend="qescape"/> itself. That happens elsewhere, right at the point that the <classname>STA</classname> gets used to build a query.</para></footnote> The conversion constructors preserve type information, so this stringization process doesn’t throw away any essential information.</para> <para><classname>STA</classname> is used anywhere MySQL++ needs to be able to accept any of several data types for use in a SQL query. Major users are <classname>Query</classname>’s template query mechanism and the <classname>Query</classname> stream quoting and escaping mechanism. You care about <classname>STA</classname> because any time you pass a data value to MySQL++ to be used in building a SQL query, it goes through <classname>STA</classname>. <classname>STA</classname> is one of the key pieces in MySQL++ that makes it easy to generate syntactically-correct SQL queries.</para> </sect3> <sect3 id="String"> <title>String</title> <para>If MySQL++ can be said to have its own generic string type, it’s <classname>String</classname>, but it’s not really functional enough for general use. It’s possible that in future versions of MySQL++ we’ll expand its interface to include everything <classname>std::string</classname> does, so that’s why it’s called that.<footnote><para>If you used MySQL++ before v3, <classname>String</classname> used to be called <classname>ColData</classname>. It was renamed because starting in v2.3, we began using it for holding more than just column data. I considered renaming it <classname>SQLString</classname> instead, but that would have confused old MySQL++ users to no end. Instead, I followed the example of <classname>Set</classname>, MySQL++’s specialized <classname>std::set</classname> variant.</para></footnote></para> <para>The key thing <classname>String</classname> provides over <classname>std::string</classname> is conversion of strings in SQL value formats to their plain old C++ data types. For example, if you initialize it with the string “2007-11-19”, you can assign the <classname>String</classname> to a <ulink type="structref" url="Date">Date</ulink>, not because <classname>Date</classname> knows how to initialize itself from <classname>String</classname>, but the reverse: <classname>String</classname> has a bunch of implicit conversion operators defined for it, so you can use it in any type context that makes sense in your application.</para> <para>Because <methodname>Row::operator[]</methodname> returns <classname>String</classname>, you can say things like this:</para> <programlisting>int x = row["x"];</programlisting> <para>In a very real sense, <classname>String</classname> is the inverse of <classname>STA</classname>: <classname>String</classname> converts SQL value strings to C++ data types, and <classname>STA</classname> converts C++ data types to SQL value strings.<footnote><para>During the development of MySQL++ v3.0, I tried merging <classname>SQLTypeAdapter</classname> and <classname>String</classname> into a single class to take advantage of this. The resulting class gave the C++ compiler the freedom to tie itself up in knots, because it was then allowed to convert almost any data type to almost any other. You’d get a tangle of ambiguous data type conversion errors from the most innocent code.</para></footnote></para> <para><classname>String</classname> has two main uses.</para> <para>By far the most common use is as the field value type of <classname>Row</classname>, as exemplified above. It’s not just the return type of <methodname>Row::operator[]</methodname>, though: it’s actually the value type used within <classname>Row</classname>’s internal array. As a result, any time MySQL++ pulls data from the database, it goes through <classname>String</classname> when converting it from the string form used in SQL result sets to the C++ data type you actually want the data in. It’s the core of the structure population mechanism in <link linkend="ssqls">the SSQLS feature</link>, for example.</para> <para>Because <classname>String</classname> is the last pristine form of data in a result set before it gets out of MySQL++’s internals where end-user code can see it, MySQL++’s <type>sql_blob</type> and related <type>typedef</type>s are aliases for <classname>String</classname>. Using anything else would require copies; while the whole “networked database server” thing means most of MySQL++ can be quite inefficient and still not affect benchmark results meaningfully, BLOBs tend to be big, so making unnecessary copies can really make a difference. Which brings us to...</para> </sect3> <sect3 id="string-refcount"> <title>Reference Counting</title> <para>To avoid unnecessary buffer copies, both <classname>STA</classname> and <classname>String</classname> are implemented in terms of a reference-counted copy-on-write buffer scheme. Both classes share the same underlying mechanism, and so are interoperable. This means that if you construct one of these objects from another, it doesn’t actually copy the string data, it only copies a pointer to the data buffer, and increments its reference count. If the object has new data assigned to it or it’s otherwise modified, it decrements its reference count and creates its own copy of the buffer. This has a lot of practical import, such as the fact that even though <methodname>Row::operator[]</methodname> returns <classname>String</classname>s by value, it’s still efficient.</para> </sect3> </sect2> <sect2 id="blob"> <title>Dealing with Binary Data</title> <para>Historically, there was no way to hold arbitrary-sized blocks of raw binary data in an SQL database. There was resistance to adding such a feature to SQL for a long time because it’s better, where possible, to decompose blocks of raw binary data into a series of numbers and text strings that <emphasis>can</emphasis> be stored in the database. This lets you query, address and manipulate elements of the data block individually.</para> <para>A classic SQL newbie mistake is trying to treat the database server as a file system. Some embedded platforms use a database engine as a file system, but MySQL doesn’t typically live in that world. When your platform already has a perfectly good file system, you should use it for big, nondecomposable blocks of binary data in most cases.</para> <para>A common example people use when discussing this is images in database-backed web applications. If you store the image in the database, you have to write code to retrieve the image from the database and send it to the client; there’s more overhead, and less efficient use of the system’s I/O caching system. If you store the image in the filesystem, all you have to do is point the web server to the directory where the images live, and put a URL for that image in your generated HTML. Because you’re giving the web server a direct path to a file on disk, operation is far more efficient. Web servers are very good at slurping whole files off of disk and sending them out to the network, and operating systems are very good at caching file accesses. Plus, you avoid the overhead of pushing the data through the high-level language your web app is written in, which is typically an interpreted language, not C++. Some people still hold out on this, claiming that database engines have superior security features, but I call bunk on that, too. Operating systems and web servers are capable of building access control systems every bit as granular and secure as a database system.</para> <para>Occasionally you really do need to store a nondecomposable block of binary data in the database. For such cases, modern SQL database servers support BLOB data types, for Binary Large OBject. This is often just called binary data, though of course all data in a modern computer is binary at some level.</para> <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. We’ve made a lot of improvements to the way MySQL++ handles <link linkend="string-types">string data</link> to avoid this problem, but it’s still possible to bypass these features, wrecking your BLOBs. These examples demonstrate correct techniques.</para> <sect3 id="blob-save"> <title>Loading a binary file into a BLOB column</title> <para>Above, I opined that it’s usually incorrect to store image data in a database, particularly with web apps, of which CGI is a primitive form. Still, it makes a nice, simple example.</para> <para>Instead of a single example program, we have here a matched pair. The first example takes the name of a JPEG file on the command line along with all the other <link linkend="examples">common example program parameters</link>, loads that file into memory, and stores it in a BLOB column in the database.</para> <para>This example also demonstrates how to retrieve the value assigned to an auto-increment column in the previous insertion. This example uses that feature in the typical way, to create unique IDs for rows as they’re inserted.</para> <para>Here 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 <type>mysqlpp::sql_blob</type> is just an alias for one of the special MySQL++ <link linkend="string-types">string types</link>, which don’t do automatic <link linkend="qescape">quoting and escaping</link>. They can’t, because MySQL++ also uses these data types to hold raw SQL query strings, which would break due to doubled quoting and/or escaping if it were automatic.</para> </sect3> <sect3 id="blob-retreive"> <title>Serving images from BLOB column via CGI</title> <para>The other example in this pair is rather short, considering how much it does. It parses a CGI query string giving the image ID, uses that to retreive data loaded into the database by <filename>load_jpeg</filename>, and writes it out in the form a web server wants when processing a CGI call, all with adequate real-world error handling. 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>While you can run it by hand, it’s best to install this in a web server’s CGI program directory, then call it with a URL like <filename>http://my.server.com/cgi-bin/cgi_jpeg?id=1</filename>. That retrieves the JPEG with ID 1 from the database and returns it to the web server, which will send it on to the browser.</para> <para>We’ve included an image with MySQL++ that you can use with this example pair, <filename>examples/logo.jpg</filename>.</para> </sect3> </sect2> <sect2 id="Transaction"> <title>Using Transactions</title> <para>The <ulink type="classref" url="Transaction"/> class makes it easier to use SQL 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/transaction.cpp</filename> illustrates this:</para> <programlisting><xi:include href="transaction.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>One of the downsides of transactions is that the locking it requires in the database server is prone to deadlocks. The classic case where this happens is when two programs both want access to the same two rows within a single transaction each, but they modify them in opposite orders. If the timing is such that the programs interleave their lock acquisitions, the two come to an impasse: neither can get access to the other row they want to modify until the other program commits its transaction and thus release the row locks, but neither can finish the transaction because they’re waiting on row locks the database server is holding on behalf of the other program.</para> <para>The MySQL server is smart enough to detect this condition, but the best it can do is abort the second transaction. This breaks the impasse, allowing the first program to complete its transaction.</para> <para>The second program now has to deal with the fact that its transaction just got aborted. There’s a subtlety in detecting this situation when using MySQL++. By default, MySQL++ signals errors like these with exceptions. In the exception handler, you might expect to get <constant>ER_LOCK_DEADLOCK</constant> from <methodname>Query::errnum()</methodname> (or <methodname>Connection::errnum()</methodname>, same thing), but what you’ll almost certainly get instead is 0, meaning “no error.” Why? It’s because you’re probably using a <classname>Transaction</classname> object to get automatic roll-backs in the face of exceptions. In this case, the roll-back happens before your exception handler is called by issuing a <command>ROLLBACK</command> query to the database server. Thus, <methodname>Query::errnum()</methodname> returns the error code associated with this roll-back query, not the deadlocked transaction that caused the exception.</para> <para>To avoid this problem, a few of the exception objects as of MySQL++ v3.0 include this last error number in the exception object itself. It’s populated at the point of the exception, so it can differ from the value you would get from <methodname>Query::errnum()</methodname> later on when the exception handler runs.</para> <para>The example <filename>examples/deadlock.cpp</filename> demonstrates the problem:</para> <programlisting><xi:include href="deadlock.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>This example works a little differently than the others. You run one copy of the example, then when it pauses waiting for you to press <keycap>Enter</keycap>, you run another copy. Then, depending on which one you press <keycap>Enter</keycap> in, one of the two will abort with the deadlock exception. You can see from the error message you get that it matters which method you call to get the error number. What you do about it is up to you as it depends on your program’s design and system architecture.</para> </sect2> <sect2 id="querytypes"> <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, <command>CREATE INDEX</command>. You do get back some information from the MySQL server, which <methodname>execute()</methodname> returns to its caller in a <ulink type="classref" url="SimpleResult"/> object. In addition to the obvious — a flag stating whether the query succeeded or not — this object also contains things like the number of rows that the query affected. If you only need the success status, it’s a little more efficient to call <methodname>Query::exec()</methodname> instead, as it simply returns <type>bool</type>.</para> <para>If your query does pull data from the database, the simplest option is <methodname>store()</methodname>. (All of the examples up to this point have used this method.) This returns a <ulink type="classref" url="StoreQueryResult"/> object, which contains the entire result set. It’s especially convenient because <classname>StoreQueryResult</classname> derives from <classname>std::vector<mysqlpp::Row></classname>, so it opens the whole panoply of STL operations for accessing the rows in the result set. Access rows randomly with subscript notation, iterate forwards and backwards over the result set, run STL algorithms on the set...it all works naturally.</para> <para>If you like the idea of storing your results in an STL container but don’t want to use <classname>std::vector</classname>, you can call <methodname>Query::storein()</methodname> instead. It lets you store the results in any standard STL container (yes, both sequential and set-associative types) instead of using <classname>StoreQueryResult</classname>. You do miss out on some of the additional database information held by <classname>StoreQueryResult</classname>’s other base class, <ulink type="classref" url="ResultBase"/>, however.</para> <para><methodname>store*()</methodname> queries are convenient, but the cost of keeping the entire result set in main memory can sometimes be too high. It can be surprisingly costly, in fact. A MySQL database server stores data compactly on disk, but it returns query data to the client in a textual form. This results in a kind of data bloat that affects numeric and BLOB types the most. MySQL++ and the underlying C API library also have their own memory overheads in addition to this. So, if you happen to know that the database server stores every record of a particular table in 1 KB, pulling a million records from that table could easily take several GB of memory with a <methodname>store()</methodname> query, depending on what’s actually stored in that table.</para> <para>For these large result sets, the superior option is a <methodname>use()</methodname> query. This returns a <ulink type="classref" url="UseQueryResult"/> object, which is similar to <classname>StoreQueryResult</classname>, 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.</para> <para>Valuable as <methodname>use()</methodname> queries are, they should not be the first resort in solving problems of excessive memory use. It’s better if you can find a way to simply not pull as much data from the database in the first place. Maybe you’re saying <command>SELECT *</command> even though you don’t immedidately need all the columns from the table. Or, maybe you’re filtering the result set with C++ code after you get it from the database server. If you can do that filtering with a more restrictive <command>WHERE</command> clause on the <command>SELECT</command>, it’ll not only save memory, it’ll save bandwidth between the database server and client, and can even save CPU time. If the filtering criteria can’t be expressed in a <command>WHERE</command> clause, however, read on to the next section.</para> </sect2> <sect2 id="store_if"> <title>Conditional Result Row Handling</title> <para>Sometimes you must pull more data from the database server than you actually need and filter it in memory. SQL’s <command>WHERE</command> clause is powerful, but not as powerful as C++. Instead of storing the full result set and 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. That 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 id="for_each"> <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 <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 id="connopts" xreflabel="connection options"> <title>Connection Options</title> <para>MySQL has a large number of options that control how it makes the connection to the database server, and how that connection behaves. The defaults are sufficient for most programs, so only one of the MySQL++ example programs make any connection option changes. Here is <filename>examples/multiquery.cpp</filename>:</para> <programlisting><xi:include href="multiquery.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> <para>This is a fairly complex example demonstrating the multi-query and stored procedure features in newer versions of MySQL. Because these are new features, and they change the communication between the client and server, you have to enable these features in a connection option. The key line is right up at the top of <function>main()</function>, where it creates a <ulink type="classref" url="MultiStatementsOption"/> object and passes it to <methodname>Connection::set_option()</methodname>. That method will take a pointer to any derivative of <ulink type="classref" url="Option"/>: you just create such an object on the heap and pass it in, which gives <classname>Connection</classname> the data values it needs to set the option. You don’t need to worry about releasing the memory used by the <classname>Option</classname> objects; it’s done automatically.</para> <para>The only tricky thing about setting options is that only a few of them can be set after the connection is up. Most need to be set just as shown in the example above: create an unconnected <classname>Connection</classname> object, set your connection options, and only then establish the connection. The option setting mechanism takes care of applying the options at the correct time in the connection establishment sequence.</para> <para>If you’re familiar with setting connection options in the MySQL C API, you’ll have to get your head around the fact that MySQL++’s connection option mechanism is a much simpler, higher-level design that doesn’t resemble the C API in any way. The C API has something like half a dozen different mechanisms for setting options that control the connection. The flexibility of the C++ type system allows us to wrap all of these up into a single high-level mechanism while actually getting greater type safety than the C API allows.</para> </sect2> <sect2 id="conn-timeout"> <title>Dealing with Connection Timeouts</title> <para>By default, current MySQL servers have an 8 hour idle timeout on connections. This is not a problem if your program never has to run for more than 8 hours or reliably queries the database more often than that. And, it’s a good thing for the database server, because even an idle connection takes up server resources.</para> <para>Many programs must run continually, however, and may experience long idle periods, such as nights and weekends when no one is around to make the program issue database queries. It’s therefore common for people writing such programs to get a bug report from the field complaining that the program died overnight or over a long weekend, usually with some error message about the database server going away. They then check the DB server, find that it’s still running and never did restart and scratch their heads wondering what happened. What happened is that the server’s connection idle timeout expired, so it closed the connection to the client.</para> <para>You cannot detect this condition by calling <methodname>Connection::connected()</methodname>. When that returns <symbol>true</symbol>, it just means that either the connect-on-create constructor or the <methodname>connect()</methodname> call succeeded and that we haven’t observed the connection to be down since then. When the database server closes an idle connection, you won’t know it until after you try to issue a query. This is simply due to the nature of network programming.</para> <para>One way around this problem is to <ulink url="http://dev.mysql.com/doc/refman/5.0/en/gone-away.html">configure MySQL</ulink> to have a longer idle timeout. This timeout is in seconds, so the default of 8 hours is 28,800 seconds. You would want to figure out the longest possible time that your program could be left idle, then pick a value somewhat longer than that. For instance, you might decide that the longest reasonable idle time is a long 4-day weekend — 345,600 seconds — which you could round up to 350,000 or 400,000 to allow for a little bit of additional idle time on either end of that period.</para> <para>Another way around this, on a per-connection basis from the client side, would be to set the <ulink type="classref" url="ReconnectOption"/> <link linkend="connopts">connection option</link>. This will cause MySQL++ to reconnect to the server automatically if it drops the connection. Beware that unless you’re using MySQL 5.1.6 or higher, you have to set this only after the connection is established, or it won’t take effect. This means there’s a potential race condition: it’s possible the connection could drop shortly enough after being established that you don’t have time to apply the option, so it won’t come back up automatically. MySQL 5.1.6+ fixes this by allowing this option to be set before the connection is established.</para> <para>A completely different way to tackle this, if your program doesn’t block forever waiting on I/O while idle, is to periodically call <methodname>Connection::ping()</methodname>. <footnote> <para>Don’t ping the server too often! It takes a tiny amount of processing capability to handle a ping, which can add up to a significant amount if done often enough by a client, or even just rarely by enough clients. Also, a lower ping frequency can let your program ride through some types of network faults — a switch reboot, for instance — without needing a reconnect. I like to ping the DB server no more often than half the connection timeout. With the default of 8 hours, then, I’d ping between every 4 and 7 hours.</para> </footnote> This sends the smallest possible amount of data to the database server, which will reset its idle timer and cause it to respond, so <methodname>ping()</methodname> returns <symbol>true</symbol>. If it returns <symbol>false</symbol> instead, you know you need to reconnect to the server. Periodic pinging is easiest to do if your program uses asynchronous I/O, <link linkend="threads">threads</link>, or some kind of event loop to ensure that you can call something periodically even while the rest of the program has nothing to do.</para> <para>An interesting variant on this strategy is to ping the server before each query, or, better, before each group of queries within a larger operation. It has an advantage over pinging during idle time in that the client is about to use far more server resources to handle the query than it will take to handle the ping, so the ping time gets lost in the overhead. On the other hand, if the client issues queries frequently when not idle, it can result in a lot more pings than would happen if you just pinged every N hours while idle.</para> <para>Finally, some programmers prefer to wrap the querying mechanism in an error handler that catches the “server has gone away” error and tries to reestablish the connection and reissue the query. This adds some complexity, but it makes your program more robust without taking up unnecessary resources. If you did this, you could even change the server to drop idle connections more often, thus tying up fewer TCP/IP stack resources.</para> </sect2> <sect2 id="concurrentqueries"> <title>Concurrent Queries on a Connection</title> <para>An important limitation of the MySQL C API library — which MySQL++ is built atop, so it shares this limitation — is that you can only have one query in progress on each connection to the database server. If you try to issue a second query while one is still in progress, you get an obscure error message about “Commands out of sync” from the underlying C API library. (You normally get this message in a MySQL++ exception unless you have exceptions disabled, in which case you get a failure code and <methodname>Connection::error()</methodname> returns this message.)</para> <para>There are lots of ways to run into this limitation:</para> <itemizedlist> <listitem> <para>The easiest way is to try to use a single <ulink type="classref" url="Connection"/> object in a multithreaded program, with more than one thread attempting to use it to issue queries. Unless you put in a lot of work to synchronize access, this is almost guaranteed to fail at some point, giving the dread “Commands out of sync” error.</para> </listitem> <listitem> <para>You might then think to give each thread that issues queries its own <classname>Connection</classname> object. You can still run into trouble if you pass the data you get from queries around to other threads. What can happen is that one of these child objects indirectly calls back to the <classname>Connection</classname> at a time where it’s involved with another query. This is properly covered elsewhere, in <xref linkend="thread-data-sharing"/>.)</para> </listitem> <listitem> <para>One way to run into this problem without using threads is with “use” queries, discussed <link linkend="querytypes">above</link>. If you don’t consume all rows from a query before you issue another on that connection, you are effectively trying to have multiple concurrent queries on a single connection. Here’s a recipie for this particular disaster:</para> <programlisting> UseQueryResult r1 = query.use("select garbage from plink where foobie='tamagotchi'"); UseQueryResult r2 = query.use("select blah from bonk where bletch='smurf'");</programlisting> <para>The second <methodname>use()</methodname> call fails because the first result set hasn’t been consumed yet.</para> </listitem> <listitem> <para>Still another way to run into this limitation is if you use MySQL’s multi-query feature. This lets you give multiple queries in a single call, separated by semicolons, and get back the results for each query separately. If you issue three queries using <methodname>Query::store()</methodname>, you only get back the first query’s results with that call, and then have to call <methodname>store_next()</methodname> to get the subsequent query results. MySQL++ provides <methodname>Query::more_results()</methodname> so you know whether you’re done, or need to call <methodname>store_next()</methodname> again. Until you reach the last result set, you can’t issue another query on that connection.</para> </listitem> <listitem> <para>Finally, there’s a way to run into this that surprises almost everyone sooner or later: stored procedures. MySQL normally returns <emphasis>at least two</emphasis> result sets for a stored procedure call. The simple case is that the stored procedure contains a single SQL query, and it succeeds: you get two results, first the results of the embedded SQL query, and then the result of the call itself. If there are multiple SQL queries within the stored procedure, you get more than two result sets. Until you consume them all, you can’t start a new query on the connection. As above, you want to have a loop calling <methodname>more_results()</methodname> and <methodname>store_next()</methodname> to work your way through all of the result sets produced by the stored procedure call.</para> </listitem> </itemizedlist> </sect2> <sect2 id="fieldinf"> <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/fieldinf.cpp</filename>:</para> <programlisting><xi:include href="fieldinf.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting> </sect2> </sect1> |
Added doc/userman/unicode.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 | <?xml version="1.0" encoding='UTF-8'?> <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <sect1 id="unicode" xreflabel="Using Unicode with MySQL++"> <title>Using Unicode with MySQL++</title> <sect2 id="unicode-history"> <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 “ç”, or they invented things like HTML entities (“&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 many Unicode-aware programs only support this subset, storing characters as 2-byte values, rather than use 4-byte characters so as to cover all possible cases, however rare. This subset of Unicode is called the Basic Multilingual Plane, or BMP.</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++ currently doesn't have any code in it for Unicode conversions; it just passes data along unchanged from the underlying MySQL C API, 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 id="unicode-unix"> <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 “ü” in “Nü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 id="unicode-windows"> <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><footnote><para>Since Windows XP, Windows actually uses the <ulink url="http://en.wikipedia.org/wiki/UTF-16">UTF-16</ulink> encoding, not UCS-2. This means that if you use characters beyond the 16-bit “BMP” range, they get encoded as 4-byte characters. But again, since the most economically valuable subset of Unicode is the BMP, many programs ignore this distinction and treat modern Windows as supporting 2-byte characters.</para></footnote>. 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 — no other OS I’m aware of uses UCS-2 — 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<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'; }</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, Windows 7, or any “Server” variant of Windows. Windows 95 and its descendants (98, ME, and CE) do not support Unicode. 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 id="unicode-refs"> <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> |
Added 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 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.docbook.org/xml/4.2/docbookx.dtd" [ <!ENTITY % xinclude SYSTEM "xinclude.mod"> %xinclude; ]> <article> <articleinfo> <title>MySQL++ v3.2.3 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-2015</year> <holder>Kevin Atkinson (original author)</holder> <holder>MySQL AB</holder> <holder>Educational Technology Resources</holder> </copyright> <pubdate><?dbtimestamp format="B d, Y"?></pubdate> </articleinfo> <xi:include href="intro.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="overview.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="tutorial.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="tquery.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="ssqls.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="unicode.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="threads.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="configuration.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="incorporating.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="breakages.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="licenses.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> </article> |
Added doc/userman/userman.dbx.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 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.docbook.org/xml/4.2/docbookx.dtd" [ <!ENTITY % xinclude SYSTEM "xinclude.mod"> %xinclude; ]> <article> <articleinfo> <title>MySQL++ v@MYSQLPP_VERSION_MAJOR@.@MYSQLPP_VERSION_MINOR@.@MYSQLPP_VERSION_BUGFIX@ 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-2015</year> <holder>Kevin Atkinson (original author)</holder> <holder>MySQL AB</holder> <holder>Educational Technology Resources</holder> </copyright> <pubdate><?dbtimestamp format="B d, Y"?></pubdate> </articleinfo> <xi:include href="intro.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="overview.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="tutorial.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="tquery.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="ssqls.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="unicode.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="threads.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="configuration.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="incorporating.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="breakages.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> <xi:include href="licenses.dbx" xmlns:xi="http://www.w3.org/2001/XInclude"/> </article> |
Deleted doc/userman/userman.xml.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added doc/userman/xinclude.mod.
> > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!ELEMENT xi:include (xi:fallback?) > <!ATTLIST xi:include xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude" href CDATA #IMPLIED parse (xml|text) "xml" xpointer CDATA #IMPLIED encoding CDATA #IMPLIED accept CDATA #IMPLIED accept-language CDATA #IMPLIED > <!ELEMENT xi:fallback ANY> <!ATTLIST xi:fallback xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude" > <!ENTITY % local.chapter.class "| xi:include"> <!ENTITY % local.divcomponent.mix "| xi:include"> <!ENTITY % local.para.char.mix "| xi:include"> |
Added dtest.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #!/bin/bash TMP=`mktemp bmXXXXXX` # Run simple unit tests first. typeset -i count=0 echo -n 'Running unit tests:' for t in test_* do if [ -x "$t" ] then errmsg=`./exrun "$t" 2>&1` errno=$? if [ "$errno" = 0 ] then count=count+1 else rm -f $TMP echo " $t FAILED ($errno)" echo echo "$errmsg" exit $? fi fi done echo " $count tests succeeded" echo 'All unit tests passed' >> $TMP # Assume AUTO_INCREMENT id column in images table will get 1 in # load_jpeg call below, since we reset the DB before doing it. export QUERY_STRING=id=1 # Now run examples to test high-level behavior. The repeated use of # resetdb is intentional! It's run after each example that changes # the database in a way that will cause a subsequent example to fail # because data it expects isn't present. echo -n 'Running examples:' for t in \ resetdb simple[0-9] store_if for_each multiquery tquery1 \ resetdb tquery[2-9] \ resetdb ssqls[0-9] \ load_jpeg cgi_jpeg do if [ -x $t ] then if [ "$t" = "resetdb" ] then echo echo -n " " fi echo -n "$t " echo "---------------- BEGIN $t OUTPUT ----------------" >> $TMP if ! ./exrun $t -D $* >> $TMP then echo echo 'TESTING ABORTED.' rm -f $TMP exit $? fi echo "================ END $t OUTPUT ================" >> $TMP echo >> $TMP fi done echo # Test ssqlsxlat -o. Note that it suppresses stdout but keeps stderr # so warnings about directives and line elements it doesn't understand # aren't suppressed. We run the first pass's output back through # ssqlsxlat to deal with comments, whitespace differences, line element # ordering, boolean value and type canonicalization, and other niggly # differences we really don't care about. diff -w isn't enough. for f in {examples,test}/*.ssqls do echo -n "Testing ssqlsxlat -i $f -o..." echo "--- BEGIN ssqlsxlat -i $f -o ERROR OUTPUT ---" >> $TMP pass1=/tmp/dtest-ssxgv2-pass1-$bnf pass2=/tmp/dtest-ssxgv2-pass2-$bnf echo -n "pass 1" ./exrun ssqlsxlat -i $f -o $pass1 > /dev/null 2>> $TMP echo -n ", pass 2" ./exrun ssqlsxlat -i $pass1 -o $pass2 > /dev/null 2>> $TMP echo -n ", diff" diff $pass1 $pass2 > /dev/null >> $TMP echo "==== END ssqlsxlat -i $f -o ERROR OUTPUT ====" >> $TMP echo done # Check for any changes BFILE=bmark.txt if [ -f $BFILE ] then if diff -u -w $BFILE $TMP then echo echo 'All tests passed.' fi rm -f $TMP else mv $TMP $BFILE chmod -w $BFILE echo echo 'BENCHMARK FILE REGENERATED.' echo fi |
Deleted examples/Makefile.am.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/Makefile.base.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/Makefile.bc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/Makefile.gcc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/Makefile.mingw.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/Makefile.simple.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/Makefile.vc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/README.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/cgi_image.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 110 111 112 113 114 115 116 117 | /*********************************************************************** 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-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "images.h" #define CRLF "\r\n" #define CRLF2 "\r\n\r\n" int main(int argc, char* argv[]) { // Get database access parameters from command line if present, else // use hard-coded values for true CGI case. mysqlpp::examples::CommandLine cmdline(argc, argv, "root", "nunyabinness"); if (!cmdline) { return 1; } // Parse CGI query string environment variable to get image ID unsigned int img_id = 0; char* cgi_query = getenv("QUERY_STRING"); if (cgi_query) { if ((strlen(cgi_query) < 4) || memcmp(cgi_query, "id=", 3)) { std::cout << "Content-type: text/plain" << std::endl << std::endl; std::cout << "ERROR: Bad query string" << std::endl; return 1; } else { img_id = atoi(cgi_query + 3); } } else { std::cerr << "Put this program into a web server's cgi-bin " "directory, then" << std::endl; std::cerr << "invoke it with a URL like this:" << std::endl; std::cerr << std::endl; std::cerr << " http://server.name.com/cgi-bin/cgi_jpeg?id=2" << std::endl; std::cerr << std::endl; std::cerr << "This will retrieve the image with ID 2." << std::endl; std::cerr << std::endl; std::cerr << "You will probably have to change some of the #defines " "at the top of" << std::endl; std::cerr << "examples/cgi_jpeg.cpp to allow the lookup to work." << std::endl; return 1; } // Retrieve image from DB by ID try { mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); mysqlpp::Query query = con.query(); query << "SELECT * FROM images WHERE id = " << img_id; mysqlpp::StoreQueryResult res = query.store(); if (res && res.num_rows()) { images img = res[0]; if (img.data.is_null) { std::cout << "Content-type: text/plain" << CRLF2; std::cout << "No image content!" << CRLF; } else { std::cout << "X-Image-Id: " << img_id << CRLF; // for debugging std::cout << "Content-type: image/jpeg" << CRLF; std::cout << "Content-length: " << img.data.data.length() << CRLF2; std::cout << img.data; } } else { std::cout << "Content-type: text/plain" << CRLF2; std::cout << "ERROR: No image with ID " << img_id << CRLF; } } catch (const mysqlpp::BadQuery& er) { // Handle any query errors std::cout << "Content-type: text/plain" << CRLF2; std::cout << "QUERY ERROR: " << er.what() << CRLF; return 1; } catch (const mysqlpp::Exception& er) { // Catch-all for any other MySQL++ exceptions std::cout << "Content-type: text/plain" << CRLF2; std::cout << "GENERAL ERROR: " << er.what() << CRLF; return 1; } return 0; } |
Added examples/cpool.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 | /*********************************************************************** cpool.cpp - ConnectionPool example. Works with both Windows native threads and POSIX threads. Shows how to create and use a concrete ConnectionPool derivative. Copyright (c) 2008-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "threads.h" #include <iostream> using namespace std; #if defined(HAVE_THREADS) // Define a concrete ConnectionPool derivative. Takes connection // parameters as inputs to its ctor, which it uses to create the // connections we're called upon to make. Note that we also declare // a global pointer to an object of this type, which we create soon // after startup; this should be a common usage pattern, as what use // are multiple pools? class SimpleConnectionPool : public mysqlpp::ConnectionPool { public: // The object's only constructor SimpleConnectionPool(mysqlpp::examples::CommandLine& cl) : conns_in_use_(0), db_(mysqlpp::examples::db_name), server_(cl.server()), user_(cl.user()), password_(cl.pass()) { } // The destructor. We _must_ call ConnectionPool::clear() here, // because our superclass can't do it for us. ~SimpleConnectionPool() { clear(); } // Do a simple form of in-use connection limiting: wait to return // a connection until there are a reasonably low number in use // already. Can't do this in create() because we're interested in // connections actually in use, not those created. Also note that // we keep our own count; ConnectionPool::size() isn't the same! mysqlpp::Connection* grab() { while (conns_in_use_ > 8) { cout.put('R'); cout.flush(); // indicate waiting for release sleep(1); } ++conns_in_use_; return mysqlpp::ConnectionPool::grab(); } // Other half of in-use conn count limit void release(const mysqlpp::Connection* pc) { mysqlpp::ConnectionPool::release(pc); --conns_in_use_; } protected: // Superclass overrides mysqlpp::Connection* create() { // Create connection using the parameters we were passed upon // creation. This could be something much more complex, but for // the purposes of the example, this suffices. cout.put('C'); cout.flush(); // indicate connection creation return new mysqlpp::Connection( db_.empty() ? 0 : db_.c_str(), server_.empty() ? 0 : server_.c_str(), user_.empty() ? 0 : user_.c_str(), password_.empty() ? "" : password_.c_str()); } void destroy(mysqlpp::Connection* cp) { // Our superclass can't know how we created the Connection, so // it delegates destruction to us, to be safe. cout.put('D'); cout.flush(); // indicate connection destruction delete cp; } unsigned int max_idle_time() { // Set our idle time at an example-friendly 3 seconds. A real // pool would return some fraction of the server's connection // idle timeout instead. return 3; } private: // Number of connections currently in use unsigned int conns_in_use_; // Our connection parameters std::string db_, server_, user_, password_; }; SimpleConnectionPool* poolptr = 0; static thread_return_t CALLBACK_SPECIFIER worker_thread(thread_arg_t running_flag) { // Ask the underlying C API to allocate any per-thread resources it // needs, in case it hasn't happened already. In this particular // program, it's almost guaranteed that the safe_grab() call below // will create a new connection the first time through, and thus // allocate these resources implicitly, but there's a nonzero chance // that this won't happen. Anyway, this is an example program, // meant to show good style, so we take the high road and ensure the // resources are allocated before we do any queries. mysqlpp::Connection::thread_start(); cout.put('S'); cout.flush(); // indicate thread started // Pull data from the sample table a bunch of times, releasing the // connection we use each time. for (size_t i = 0; i < 6; ++i) { // Go get a free connection from the pool, or create a new one // if there are no free conns yet. Uses safe_grab() to get a // connection from the pool that will be automatically returned // to the pool when this loop iteration finishes. mysqlpp::ScopedConnection cp(*poolptr, true); if (!cp) { cerr << "Failed to get a connection from the pool!" << endl; break; } // Pull a copy of the sample stock table and print a dot for // each row in the result set. mysqlpp::Query query(cp->query("select * from stock")); mysqlpp::StoreQueryResult res = query.store(); for (size_t j = 0; j < res.num_rows(); ++j) { cout.put('.'); } // Delay 1-4 seconds before doing it again. Because this can // delay longer than the idle timeout, we'll occasionally force // the creation of a new connection on the next loop. sleep(rand() % 4 + 1); } // Tell main() that this thread is no longer running *reinterpret_cast<bool*>(running_flag) = false; cout.put('E'); cout.flush(); // indicate thread ended // Release the per-thread resources before we exit mysqlpp::Connection::thread_end(); return 0; } #endif int main(int argc, char *argv[]) { #if defined(HAVE_THREADS) // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Create the pool and grab a connection. We do it partly to test // that the parameters are good before we start doing real work, and // partly because we need a Connection object to call thread_aware() // on to check that it's okay to start doing that real work. This // latter check should never fail on Windows, but will fail on most // other systems unless you take positive steps to build with thread // awareness turned on. See README-*.txt for your platform. poolptr = new SimpleConnectionPool(cmdline); try { mysqlpp::ScopedConnection cp(*poolptr, true); if (!cp->thread_aware()) { cerr << "MySQL++ wasn't built with thread awareness! " << argv[0] << " can't run without it." << endl; return 1; } } catch (mysqlpp::Exception& e) { cerr << "Failed to set up initial pooled connection: " << e.what() << endl; return 1; } // Setup complete. Now let's spin some threads... cout << endl << "Pool created and working correctly. Now to do " "some real work..." << endl; srand((unsigned int)time(0)); bool running[] = { true, true, true, true, true, true, true, true, true, true, true, true, true, true }; const size_t num_threads = sizeof(running) / sizeof(running[0]); size_t i; for (i = 0; i < num_threads; ++i) { if (int err = create_thread(worker_thread, running + i)) { cerr << "Failed to create thread " << i << ": error code " << err << endl; return 1; } } // Test the 'running' flags every second until we find that they're // all turned off, indicating that all threads are stopped. cout.put('W'); cout.flush(); // indicate waiting for completion do { sleep(1); i = 0; while (i < num_threads && !running[i]) ++i; } while (i < num_threads); cout << endl << "All threads stopped!" << endl; // Shut it all down... delete poolptr; cout << endl; #else (void)argc; // warning squisher cout << argv[0] << " requires that threads be enabled!" << endl; #endif return 0; } |
Deleted examples/custom1.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/custom2.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/custom3.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/custom4.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/custom5.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/custom6.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to examples/dbinfo.cpp.
1 2 3 4 | /*********************************************************************** dbinfo.cpp - Example showing how to request information about the database schema, such as table names, column types, etc. | | | | | | > < < > | | > | > > > > > | | > | < < | < < < | > | < | < | | | < < < < < < < < | | | | < | | | | < | < | > | < < | < | > | | > > > > | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | < | | | | | | | | | > > > > > > > > > | > | > > > > > > > > | | | < < | | | < < < > > > > > > | | < < < < | < | > > > > > > > | < < < < < < < | | 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 | /*********************************************************************** 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-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <mysql++.h> #include <iomanip> #include <iostream> #include <string> #include <vector> using namespace std; // Insert a bar into the stream with the given query string centered static void separator(ostream& os, string qstr) { string sep("========================================" "========================================"); if (qstr.size()) { string::size_type start = (sep.size() - qstr.size()) / 2; sep.replace(start - 1, 1, 1, ' '); sep.replace(start, qstr.size(), qstr); sep.replace(start + qstr.size(), 1, 1, ' '); os << "\n\n"; } os << sep << endl; } // Print out the MySQL server version static void show_mysql_version(mysqlpp::Connection& con) { separator(cout, ""); cout << "MySQL version: " << con.client_version(); } // Print out the names of all the databases managed by the server static void show_databases(mysqlpp::Connection& con) { mysqlpp::Query query = con.query("show databases"); separator(cout, query.str()); mysqlpp::StoreQueryResult res = query.store(); cout << "Databases found: " << res.size(); cout.setf(ios::left); mysqlpp::StoreQueryResult::iterator rit; for (rit = res.begin(); rit != res.end(); ++rit) { cout << "\n\t" << (*rit)[0]; } } // Print information about each of the tables we found static void show_table_info(mysqlpp::Connection& con, const vector<string>& tables) { vector<string>::const_iterator it; for (it = tables.begin(); it != tables.end(); ++it) { mysqlpp::Query query = con.query(); query << "describe " << *it; separator(cout, query.str()); mysqlpp::StoreQueryResult res = query.store(); size_t columns = res.num_fields(); vector<size_t> widths; for (size_t i = 0; i < columns; ++i) { string s = res.field_name(int(i)); 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[i]) { cout << '|' << setw(widths[i]) << res.field_name(int(i)) << '|'; } } cout << endl; mysqlpp::StoreQueryResult::iterator rit; for (rit = res.begin(); rit != res.end(); ++rit) { for (unsigned int i = 0; i < columns; ++i) { if (widths[i]) { cout << ' ' << setw(widths[i]) << (*rit)[i].c_str() << ' '; } } cout << endl; } } } // Print out the names of all tables in the sample database, and // return the list of tables. static void show_tables(mysqlpp::Connection& con) { mysqlpp::Query query = con.query("show tables"); separator(cout, query.str()); mysqlpp::StoreQueryResult res = query.store(); cout << "Tables found: " << res.size(); cout.setf(ios::left); vector<string> tables; mysqlpp::StoreQueryResult::iterator rit; for (rit = res.begin(); rit != res.end(); ++rit) { string tbl((*rit)[0]); cout << "\n\t" << tbl; tables.push_back(tbl); } show_table_info(con, tables); } // Call all the above functions in sequence int main(int argc, char* argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Connect to server, then dump a bunch of stuff we find on it mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); show_mysql_version(con); show_databases(con); show_tables(con); } catch (const mysqlpp::BadQuery& er) { // Handle any query errors cerr << "Query error: " << er.what() << 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/deadlock.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 | /*********************************************************************** deadlock.cpp - Demonstrates how MySQL's deadlock detection interacts with MySQL++'s Transaction class an exception handling mechanism. Run one copy of this program with the -m1 command line switch, then while it's waiting for you to press Enter, run another copy with -m2 instead. Copyright (c) 2007 by Jim Wallace and (c) 2007-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include <mysql++.h> #include <mysqld_error.h> #include <iostream> using namespace std; // Bring in global holding the value given to the -m switch extern int run_mode; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Check that the mode parameter was also given and it makes sense const int run_mode = cmdline.run_mode(); if ((run_mode != 1) && (run_mode != 2)) { cerr << argv[0] << " must be run with -m1 or -m2 as one of " "its command-line arguments." << endl; return 1; } mysqlpp::Connection con; try { // Establish the connection to the database server mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Start a transaction set. Transactions create mutex locks on // modified rows, so if two programs both touch the same pair of // rows but in opposite orders at the wrong time, one of the two // programs will deadlock. The MySQL server knows how to detect // this situation, and its error return causes MySQL++ to throw // a BadQuery exception. The point of this example is that if // you want to detect this problem, you would check the value of // BadQuery::errnum(), not Connection::errnum(), because the // transaction rollback process executes a query which succeeds, // setting the MySQL C API's "last error number" value to 0. // The exception object carries its own copy of the error number // at the point the exception was thrown for this very reason. mysqlpp::Query query = con.query(); mysqlpp::Transaction trans(con); // Build and run the queries, with the order depending on the -m // flag, so that a second copy of the program will deadlock if // run while the first is waiting for Enter. char dummy[100]; for (int i = 0; i < 2; ++i) { int lock = run_mode + (run_mode == 1 ? i : -i); cout << "Trying lock " << lock << "..." << endl; query << "select * from deadlock_test" << lock << " where x = " << lock << " for update"; query.store(); cout << "Acquired lock " << lock << ". Press Enter to "; cout << (i == 0 ? "try next lock" : "exit"); cout << ": " << flush; cin.getline(dummy, sizeof(dummy)); } } catch (mysqlpp::BadQuery e) { if (e.errnum() == ER_LOCK_DEADLOCK) { cerr << "Transaction deadlock detected!" << endl; cerr << "Connection::errnum = " << con.errnum() << ", BadQuery::errnum = " << e.errnum() << endl; } else { cerr << "Unexpected query error: " << e.what() << endl; } return 1; } catch (mysqlpp::Exception e) { cerr << "General error: " << e.what() << endl; return 1; } return 0; } |
Added examples/fieldinf.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 | /*********************************************************************** fieldinf.cpp - Shows how to request information about the fields in a table, such as their SQL and C++-equivalent types. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <iostream> #include <iomanip> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Get contents of main example table mysqlpp::Query query = con.query("select * from stock"); mysqlpp::StoreQueryResult res = query.store(); // Show info about each field in that table char widths[] = { 12, 22, 46 }; cout.setf(ios::left); cout << setw(widths[0]) << "Field" << setw(widths[1]) << "SQL Type" << setw(widths[2]) << "Equivalent C++ Type" << endl; for (size_t i = 0; i < sizeof(widths) / sizeof(widths[0]); ++i) { cout << string(widths[i] - 1, '=') << ' '; } cout << endl; for (size_t i = 0; i < res.field_names()->size(); i++) { // Suppress C++ type name outputs when run under dtest, // as they're system-specific. const char* cname = res.field_type(int(i)).name(); mysqlpp::FieldTypes::value_type ft = res.field_type(int(i)); ostringstream os; os << ft.sql_name() << " (" << ft.id() << ')'; cout << setw(widths[0]) << res.field_name(int(i)).c_str() << setw(widths[1]) << os.str() << setw(widths[2]) << cname << endl; } cout << endl; // Simple type check if (res.field_type(0) == typeid(string)) { cout << "SQL type of 'item' field most closely resembles " "the C++ string type." << endl; } // Tricky type check: the 'if' path shouldn't happen because the // description field has the NULL attribute. We need to dig a // little deeper if we want to ignore this in our type checks. if (res.field_type(5) == typeid(string)) { cout << "Should not happen! Type check failure." << endl; } else if (res.field_type(5) == typeid(mysqlpp::sql_blob_null)) { cout << "SQL type of 'description' field resembles " "a nullable variant of the C++ string type." << endl; } else { cout << "Weird: fifth field's type is now " << res.field_type(5).name() << endl; cout << "Did something recently change in resetdb?" << endl; } } catch (const mysqlpp::BadQuery& er) { // Handle any query errors cerr << "Query error: " << er.what() << 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/fieldinf1.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 105 106 107 108 109 | /*********************************************************************** for_each.cpp - Demonstrates Query::for_each(), showing how to perform an arbitrary action on each row in a result set. Copyright (c) 2005-2009 by Educational Technology Resources, Inc. and (c) 2007 by Switchplane, Ltd. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.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.data); } 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[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // 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; } |
Added examples/images.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 | /*********************************************************************** images.h - Declares the images table SSQLS. Copyright (c) 2008-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <ssqls.h> sql_create_2(images, 1, 2, mysqlpp::sql_int_unsigned_null, id, mysqlpp::sql_blob_null, data) |
Deleted examples/load_file.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 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 | /*********************************************************************** load_jpeg.cpp - Example showing how to insert BLOB data into the database from a file. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "images.h" #include "printdata.h" #include <fstream> using namespace std; using namespace mysqlpp; // This is just an implementation detail for the example. Skip down to // main() for the concept this example is trying to demonstrate. You // can simply assume that, given a BLOB containing a valid JPEG, it // returns true. static bool is_jpeg(const mysqlpp::sql_blob& img, const char** whynot) { // See http://stackoverflow.com/questions/2253404/ for // justification for the various tests. const unsigned char* idp = reinterpret_cast<const unsigned char*>(img.data()); if (img.size() < 125) { *whynot = "a valid JPEG must be at least 125 bytes"; } else if ((idp[0] != 0xFF) || (idp[1] != 0xD8)) { *whynot = "file does not begin with JPEG sigil bytes"; } else if ((memcmp(idp + 6, "JFIF", 4) != 0) && (memcmp(idp + 6, "Exif", 4) != 0)) { *whynot = "file does not contain JPEG type word"; } else { *whynot = 0; return true; } return false; } // Skip to main() before studying this. This is a little too // low-level to bother with on your first pass thru the code. static bool load_jpeg_file(const mysqlpp::examples::CommandLine& cmdline, images& img, string& img_name) { if (cmdline.extra_args().size() == 0) { // Nothing for us to do here. Caller will insert NULL BLOB. return true; } // Got a file's name on the command line, so open it. img_name = cmdline.extra_args()[0]; ifstream img_file(img_name.c_str(), ios::binary); if (img_file) { // Slurp file contents into RAM with minimum copying. (Idiom // explained here: http://stackoverflow.com/questions/116038/) // // By loading the file into a C++ string (stringstream::str()) // and assigning that directly to a mysqlpp::sql_blob, we avoid // truncating the binary data at the first null character. img.data.data = static_cast<const stringstream*>( &(stringstream() << img_file.rdbuf()))->str(); // Check JPEG data for sanity. const char* error; if (is_jpeg(img.data.data, &error)) { return true; } else { cerr << '"' << img_name << "\" isn't a JPEG: " << error << '!' << endl; } } cmdline.print_usage("[jpeg_file]"); return false; } int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Load the file named on the command line images img(mysqlpp::null, mysqlpp::null); string img_name("NULL"); if (load_jpeg_file(cmdline, img, img_name)) { // Insert image data or SQL NULL into the images.data BLOB // column. The key here is that we're holding the raw // binary data in a mysqlpp::sql_blob, which avoids data // conversion problems that can lead to treating BLOB data // as C strings, thus causing null-truncation. The fact // that we're using SSQLS here is a side issue, simply // demonstrating that mysqlpp::Null<mysqlpp::sql_blob> is // now legal in SSQLS, as of MySQL++ 3.0.7. Query query = con.query(); query.insert(img); SimpleResult res = query.execute(); // Report successful insertion cout << "Inserted \"" << img_name << "\" into images table, " << img.data.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; } |
Added examples/logo.jpg.
cannot compute difference between binary files
Changes to examples/multiquery.cpp.
1 2 | /*********************************************************************** multiquery.cpp - Example showing how to iterate over result sets upon | | | | | | | | > > | | | | | | | | | | < | | > | < | < | | | | | | < < < < < < | > > > > > | | > | < < > > | < | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | /*********************************************************************** 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-2001 by MySQL AB, (c) 2004-2009 by Educational Technology Resources, Inc., and (c) 2005 by Arnon Jalon. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <mysql++.h> #include <algorithm> #include <iostream> #include <iomanip> #include <vector> using namespace std; using namespace mysqlpp; typedef vector<size_t> IntVectorType; static void print_header(IntVectorType& widths, StoreQueryResult& res) { cout << " |" << setfill(' '); for (size_t i = 0; i < res.field_names()->size(); i++) { cout << " " << setw(widths.at(i)) << res.field_name(int(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[int(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(StoreQueryResult& res, int index) { // Show how many rows are in result, if any StoreQueryResult::size_type 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; size_t size = res.num_fields(); for (size_t i = 0; i < size; i++) { widths.push_back(max( res.field(i).max_length(), res.field_name(i).size())); } // Print result set header print_row_separator(widths); print_header(widths, res); print_row_separator(widths); // Display the result set contents for (StoreQueryResult::size_type i = 0; i < num_results; ++i) { print_row(widths, res[i]); } // Print result set footer print_row_separator(widths); } static void print_multiple_results(Query& query) { // Execute query and print all result sets StoreQueryResult res = query.store(); print_result(res, 0); for (int i = 1; query.more_results(); ++i) { res = query.store_next(); print_result(res, i); } } int main(int argc, char *argv[]) { // Get connection parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Enable multi-queries. Notice that you almost always set // MySQL++ connection options before establishing the server // connection, and options are always set using this one // interface. If you're familiar with the underlying C API, // you know that there is poor consistency on these matters; // MySQL++ abstracts these differences away. Connection con; con.set_option(new MultiStatementsOption(true)); // Connect to the database if (!con.connect(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass())) { return 1; } // Set up query with multiple queries. Query query = con.query(); query << "DROP TABLE IF EXISTS test_table; " << "CREATE TABLE test_table(id INT); " << "INSERT INTO test_table VALUES(10); " << "UPDATE test_table SET id=20 WHERE id=10; " << "SELECT * FROM test_table; " << "DROP TABLE test_table"; cout << "Multi-query: " << endl << query << 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 << "DROP PROCEDURE IF EXISTS get_stock; " << "CREATE PROCEDURE get_stock" << "( i_item varchar(20) ) " << "BEGIN " << "SET i_item = concat('%', i_item, '%'); " << "SELECT * FROM stock WHERE lower(item) like lower(i_item); " << "END;"; cout << "Stored procedure query: " << endl << query << endl; // Create the stored procedure. print_multiple_results(query); // Call the stored procedure and display its results. query << "CALL get_stock('relish')"; cout << "Query: " << query << endl; print_multiple_results(query); #endif return 0; } catch (const BadOption& err) { cerr << err.what() << endl; cerr << "This example requires MySQL 4.1.1 or later." << 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; } } |
Added examples/printdata.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 | /*********************************************************************** printdata.cpp - Utility functions for printing out data in common formats, required by most of the example programs. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "printdata.h" #include <iostream> #include <iomanip> using namespace std; //// print_stock_header //////////////////////////////////////////////// // Display a header suitable for use with print_stock_rows(). void print_stock_header(size_t rows) { cout << "Records found: " << rows << endl << endl; cout.setf(ios::left); cout << setw(31) << "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_decimal_null price, const mysqlpp::sql_date& date) { cout << setw(30) << 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) { print_stock_row(string(row[0]), row[1], 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::StoreQueryResult& res) { print_stock_header(res.size()); // Use the StoreQueryResult class's read-only random access iterator to walk // through the query results. mysqlpp::StoreQueryResult::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); } } //// print_stock_table ///////////////////////////////////////////////// // Simply retrieve and print the entire contents of the stock table. void print_stock_table(mysqlpp::Query& query) { // Reset query object to its pristine state in case it's been used // before by our caller for template queries. query.reset(); // Build the query itself, and show it to the user query << "select * from stock"; cout << "Query: " << query << endl; // Execute it, and display the results mysqlpp::StoreQueryResult res = query.store(); print_stock_rows(res); } |
Added examples/printdata.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 | /*********************************************************************** printdata.h - Declares utility routines for printing out data in common forms, used by most of the example programs. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_PRINTDATA_H) #define MYSQLPP_PRINTDATA_H #include <mysql++.h> void print_stock_header(size_t 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_decimal_null price, const mysqlpp::sql_date& date); void print_stock_rows(mysqlpp::StoreQueryResult& res); void print_stock_table(mysqlpp::Query& query); #endif // !defined(MYSQLPP_PRINTDATA_H) |
Changes to examples/resetdb.cpp.
1 2 | /*********************************************************************** resetdb.cpp - (Re)initializes the example database, mysql_cpp_data. | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > | | | | | | > > > | | < | > | > > > | > > > > > | > | | > | | | > > > > > > > > > > > > > > > > > > > > > > > > | | | | 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 | /*********************************************************************** 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-2001 by MySQL AB, and (c) 2004-2009 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 "cmdline.h" #include "printdata.h" #include <mysql++.h> #include <iostream> #include <cstdio> using namespace std; // Pull in the sample database name from the cmdline module. extern const char* kpcSampleDatabase; // 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; } // Get connection parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Connect to database server mysqlpp::Connection con; try { if (cmdline.dtest_mode()) { cout << "Connecting to database server..." << endl; } else { const char* u = cmdline.user() ? cmdline.user() : ""; const char* s = cmdline.server() ? cmdline.server() : "localhost"; cout << "Connecting to '" << u << "'@'" << s << "', with" << (cmdline.pass() && cmdline.pass()[0] ? "" : "out") << " password..." << endl; } con.connect(0, cmdline.server(), cmdline.user(), cmdline.pass()); } 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(mysqlpp::examples::db_name)) { // Toss old tables, ignoring errors because it would just // mean the table doesn't exist, which doesn't matter. cout << "Dropping existing sample data tables..." << endl; query.exec("drop table stock"); query.exec("drop table images"); query.exec("drop table deadlock_test1"); query.exec("drop table deadlock_test2"); } else { // Database doesn't exist yet, so create and select it. if (con.create_db(mysqlpp::examples::db_name) && con.select_db(mysqlpp::examples::db_name)) { 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(30) NOT NULL, " << " num BIGINT NOT NULL, " << " weight DOUBLE NOT NULL, " << " price DECIMAL(6,2) NULL, " << // NaN & inf. == NULL " sdate DATE NOT NULL, " << " description MEDIUMTEXT NULL) " << "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 %6:table values " << "(%0q, %1q, %2, %3, %4q, %5q:desc)"; query.parse(); // Set a default for template query parameters "table" and "desc". query.template_defaults["table"] = "stock"; query.template_defaults["desc"] = mysqlpp::null; // 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..." << flush; 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", "good American yellow mustard, not that European stuff"); query.execute("Hotdog Buns", 65, 1.1, 1.1, "1998-04-23"); // Test that above did what we wanted. cout << "inserted " << con.count_rows("stock") << " rows." << endl; // Now create empty images table, for testing BLOB and auto- // increment column features. cout << "Creating empty images table..." << endl; query.reset(); // forget template query info query << "CREATE TABLE images (" << " id INT UNSIGNED AUTO_INCREMENT, " << " data BLOB, " << " PRIMARY KEY (id)" << ")"; query.execute(); // Create the tables used by examples/deadlock.cpp cout << "Creating deadlock testing tables..." << endl; query.execute("CREATE TABLE deadlock_test1 (x INT) ENGINE=innodb"); query.execute("CREATE TABLE deadlock_test2 (x INT) ENGINE=innodb"); query.execute("INSERT INTO deadlock_test1 VALUES (1);"); query.execute("INSERT INTO deadlock_test2 VALUES (2);"); // Report success cout << (new_db ? "Created" : "Reinitialized") << " sample database successfully." << endl; } catch (const mysqlpp::BadQuery& er) { // Handle any query errors cerr << endl << "Query error: " << er.what() << endl; return 1; } catch (const mysqlpp::BadConversion& er) { // Handle bad conversions cerr << endl << "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 << endl << "Error: " << er.what() << endl; return 1; } return 0; } |
Changes to examples/simple1.cpp.
1 2 | /*********************************************************************** simple1.cpp - Example showing the simplest way to get data from a 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 | /*********************************************************************** simple1.cpp - Example showing the simplest way to get data from a MySQL table with MySQL++. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <mysql++.h> #include <iostream> #include <iomanip> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Connect to the sample database. mysqlpp::Connection conn(false); if (conn.connect(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass())) { // Retrieve a subset of the sample stock table set up by resetdb // and display it. mysqlpp::Query query = conn.query("select item from stock"); if (mysqlpp::StoreQueryResult res = query.store()) { cout << "We have:" << endl; mysqlpp::StoreQueryResult::const_iterator it; for (it = res.begin(); it != res.end(); ++it) { mysqlpp::Row row = *it; cout << '\t' << row[0] << endl; } } else { cerr << "Failed to get item list: " << query.error() << endl; return 1; } return 0; } else { cerr << "DB connection failed: " << conn.error() << endl; return 1; } } |
Changes to examples/simple2.cpp.
1 2 | /*********************************************************************** simple2.cpp - Retrieves the entire contents of the sample stock table | | | | | | | > | | | > > > > | | < | | | | | | | | | | | < < | | | | | | | | | | | > > > > > > > | < < | 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 | /*********************************************************************** 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-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <mysql++.h> #include <iostream> #include <iomanip> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Connect to the sample database. mysqlpp::Connection conn(false); if (conn.connect(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass())) { // Retrieve the sample stock table set up by resetdb mysqlpp::Query query = conn.query("select * from stock"); mysqlpp::StoreQueryResult res = query.store(); // Display results if (res) { // Display header cout.setf(ios::left); cout << setw(31) << "Item" << setw(10) << "Num" << setw(10) << "Weight" << setw(10) << "Price" << "Date" << endl << endl; // Get each row in result set, and print its contents for (size_t i = 0; i < res.num_rows(); ++i) { cout << setw(30) << res[i]["item"] << ' ' << setw(9) << res[i]["num"] << ' ' << setw(9) << res[i]["weight"] << ' ' << setw(9) << res[i]["price"] << ' ' << setw(9) << res[i]["sdate"] << endl; } } else { cerr << "Failed to get stock table: " << query.error() << endl; return 1; } return 0; } else { cerr << "DB connection failed: " << conn.error() << endl; return 1; } } |
Changes to examples/simple3.cpp.
1 2 3 4 5 | /*********************************************************************** 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. | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | /*********************************************************************** 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-2009 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 |
︙ | ︙ | |||
21 22 23 24 25 26 27 | 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 ***********************************************************************/ | | > | | | > > > > | | > > | < < | < < | | | | | | | | < | | | | | | | | > > > > > > > | > > > > > | | 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 | 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 "cmdline.h" #include "printdata.h" #include <mysql++.h> #include <iostream> #include <iomanip> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Connect to the sample database. mysqlpp::Connection conn(false); if (conn.connect(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass())) { // Ask for all rows from the sample stock table and display // them. Unlike simple2 example, we retreive each row one at // a time instead of storing the entire result set in memory // and then iterating over it. mysqlpp::Query query = conn.query("select * from stock"); if (mysqlpp::UseQueryResult res = query.use()) { // Display header cout.setf(ios::left); cout << setw(31) << "Item" << setw(10) << "Num" << setw(10) << "Weight" << setw(10) << "Price" << "Date" << endl << endl; // Get each row in result set, and print its contents while (mysqlpp::Row row = res.fetch_row()) { cout << setw(30) << row["item"] << ' ' << setw(9) << row["num"] << ' ' << setw(9) << row["weight"] << ' ' << setw(9) << row["price"] << ' ' << setw(9) << row["sdate"] << endl; } // Check for error: can't distinguish "end of results" and // error cases in return from fetch_row() otherwise. if (conn.errnum()) { cerr << "Error received in fetching a row: " << conn.error() << endl; return 1; } return 0; } else { cerr << "Failed to get stock item: " << query.error() << endl; return 1; } } else { cerr << "DB connection failed: " << conn.error() << endl; return 1; } } |
Added examples/ssqls1.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 | /*********************************************************************** ssqls1.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-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <iostream> #include <vector> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Retrieve a subset of the stock table's columns, and store // the data in a vector of 'stock' SSQLS structures. See the // user manual for the consequences arising from this quiet // ability to store a subset of the table in the stock SSQLS. mysqlpp::Query query = con.query("select item,description from stock"); vector<stock> res; query.storein(res); // Display the items cout << "We have:" << endl; vector<stock>::iterator it; for (it = res.begin(); it != res.end(); ++it) { cout << '\t' << it->item; if (it->description != mysqlpp::null) { cout << " (" << it->description << ")"; } cout << 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; } |
Added examples/ssqls2.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 | /*********************************************************************** ssqls2.cpp - Example showing how to insert a row using the Specialized SQL Structures feature of MySQL++. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <iostream> #include <limits> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // 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, numeric_limits<double>::infinity(), // "priceless," ha! mysqlpp::sql_date("1998-09-25"), mysqlpp::null); // 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 << endl; // Execute the query. We use execute() because INSERT doesn't // return a result set. query.execute(); // Retrieve and print out 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; } |
Added examples/ssqls3.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 | /*********************************************************************** ssqls3.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-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Build a query to retrieve the stock item that has Unicode // characters encoded in UTF-8 form. mysqlpp::Query query = con.query("select * from stock "); query << "where item = " << mysqlpp::quote << "Nürnberger Brats"; // Retrieve the row, throwing an exception if it fails. mysqlpp::StoreQueryResult 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[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 << endl; // Run the query with execute(), since UPDATE doesn't return a // result set. query.execute(); // Retrieve and print out 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; } |
Added examples/ssqls4.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 | /*********************************************************************** ssqls4.cpp - Example very similar to ssqls1.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-2001 by MySQL AB, and (c) 2004-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // 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 ssqls1.cpp. It works because // SSQLS objects are less-than comparable. mysqlpp::Query query = con.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; } |
Added examples/ssqls5.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 | /*********************************************************************** ssqls5.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-2001 by MySQL AB, (c) 2004-2009 by Educational Technology Resources, Inc., and (c) 2005 by Chris Frey. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <iostream> #include <vector> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Get all the rows in the stock table. mysqlpp::Query query = con.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 << "select * from stock where " << res[0].equal_list(" and ", stock_weight, stock_price); // Display the finished query. cout << "Custom query:\n" << query << 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/ssqls6.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 | /*********************************************************************** ssqls6.cpp - Example showing how to insert a collection row using the Specialized SQL Structures feature of MySQL++ and Query::insertfrom(). Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, (c) 2004-2009 by Educational Technology Resources, Inc., (c) 2008 by AboveNet, 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <fstream> using namespace std; // Breaks a given text line of tab-separated fields up into a list of // strings. static size_t tokenize_line(const string& line, vector<mysqlpp::String>& strings) { string field; strings.clear(); istringstream iss(line); while (getline(iss, field, '\t')) { strings.push_back(mysqlpp::String(field)); } return strings.size(); } // Reads a tab-delimited text file, returning the data found therein // as a vector of stock SSQLS objects. static bool read_stock_items(const char* filename, vector<stock>& stock_vector) { ifstream input(filename); if (!input) { cerr << "Error opening input file '" << filename << "'" << endl; return false; } string line; vector<mysqlpp::String> strings; while (getline(input, line)) { if (tokenize_line(line, strings) == 6) { stock_vector.push_back(stock(string(strings[0]), strings[1], strings[2], strings[3], strings[4], strings[5])); } else { cerr << "Error parsing input line (doesn't have 6 fields) " << "in file '" << filename << "'" << endl; cerr << "invalid line: '" << line << "'" << endl; } } return true; } int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } // Read in a tab-delimited file of stock data vector<stock> stock_vector; if (!read_stock_items("examples/stock.txt", stock_vector)) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Clear all existing rows from stock table, as we're about to // insert a bunch of new ones, and we want a clean slate. mysqlpp::Query query = con.query(); query.exec("DELETE FROM stock"); // Insert data read from the CSV file, allowing up to 1000 // characters per packet. We're using a small size in this // example just to force multiple inserts. In a real program, // you'd want to use larger packets, for greater efficiency. mysqlpp::Query::MaxPacketInsertPolicy<> insert_policy(1000); query.insertfrom(stock_vector.begin(), stock_vector.end(), insert_policy); // Retrieve and print out 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::BadInsertPolicy& er) { // Handle bad conversions cerr << "InsertPolicy error: " << er.what() << 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/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 | /*********************************************************************** stock.h - Declares the stock SSQLS used by several of the examples. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <ssqls.h> // The following is calling a very complex macro which will create // "struct stock", which has the member variables: // // sql_char item; // ... // sql_mediumtext_null description; // // plus methods to help populate the class from a MySQL row. See the // SSQLS sections in the user manual for further details. sql_create_6(stock, 1, 6, // 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_null, price, mysqlpp::sql_date, sDate, // SSQLS isn't case-sensitive! mysqlpp::sql_mediumtext_null, description) |
Added examples/stock.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Tiny Screws 1000 0.01 0.05 2008-11-11 All those tiny, indistinguishable, but slighly different screws like the ones it the bottom of your computer desk drawer. Needle-nose Pliers 50 0.5 5.95 2008-11-12 Drop-forged steel, rubberized grip Small Soldering Iron 40 0.5 15.95 2008-09-01 20-watt model, assorted tips, UL approved Large Soldering Iron 35 0.75 24.95 2008-08-01 40-watt model, assorted tips, UL approved, stand included Solder Wick 100 0.1 2.95 2008-04-01 25 feet, braided copper Mini Screwdrivers, 3 pc. 30 0.4 8.95 2008-03-25 3-piece mini-screwdriver set in plastic case, 2 Phillips, 1 standard slot Mini Screwdrivers, 6 pc. 40 0.6 12.95 2008-04-01 6-piece mini-screwdriver set in plastic case, 3 Phillips, 3 standard slot Wire-wrapping Tool 25 0.2 4.95 2008-04-23 wire-wrapping tool with rubberied grip Red LED, 5mm, 3000mcd 300 0.01 0.29 2008-10-02 Max forward current 20mA continuous. Max Forward Drop: 2.1V. Max reverse Voltage:5VDC. Orange LED, 5mm, 2500mcd 250 0.01 0.29 2008-07-31 Max forward current 20mA continuous, 5VDC Max reverse Voltage. 2VDC (typ) Forward voltage drop. 30 Deg. view angle. 1" leads. Yellow LED, 5mm, 3000mcd 400 0.01 0.25 2008-09-30 Max forward current 20mA continuous, 5VDC Max reverse Voltage. 2.2VDC (typ) Forward voltage drop. 30 Deg. view angle. 1" leads. Green LED, 5mm, 1000mcd 350 0.01 0.45 2008-09-27 Max forward current 20mA continuous, 5VDC Max reverse Voltage. 2VDC (typ) Forward voltage drop. 30 Deg. view angle. 1" leads. Blue LED, 5mm, 3900mcd 500 0.01 0.34 2007-12-01 Max forward current 20mA continuous, 5VDC Max reverse Voltage. 2.2VDC (typ) Forward voltage drop. 30 Deg. view angle. 1" leads. White LED, 5mm, 15000mcd 750 0.01 0.43 2008-02-01 Max forward current 30mA continuous, 20mA recommended. 5VDC Max reverse Voltage. 3.8VDC typ. 4.5V max. Forward voltage drop. 15deg. View angle. 1" leads. AA Battery, single 220 0.05 0.50 2007-09-19 1.5 v, alkaline AA Battery, 4-pack 60 0.20 1.79 2007-08-03 1.5 v, alkaline AA Battery, 24-pack 8 1.2 9.99 2007-04-25 1.5 v, alkaline, includes tester C Battery, single 100 0.075 0.65 2007-11-14 1.5 v, alkaline C Battery, 4-pack 25 0.3 2.29 2007-06-05 1.5 v, alkaline C Battery, 24-pack 5 1.8 10.99 2007-06-13 1.5 v, alkaline, includes tester D Battery, single 180 0.08 0.70 2007-12-03 1.5 v, alkaline D Battery, 4-pack 45 0.3 2.59 2007-04-01 1.5 v, alkaline D Battery, 24-pack 12 1.9 11.99 2007-05-15 1.5 v, alkaline, includes tester 9-volt Battery, single 90 0.06 0.75 2008-01-02 alkaline 9-volt Battery, 3-pack 17 0.2 1.99 2008-02-28 alkaline 9-volt Batter, 20-pack 12 1.2 12.99 2007-12-28 alkaline, no tester needed (just use your tongue) |
Added 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 100 101 102 103 104 | /*********************************************************************** 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-2010 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 "cmdline.h" #include "printdata.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 than 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[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // 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; } |
Added examples/threads.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 | /*********************************************************************** threads.h - Abstracts away the differences between POSIX threads and Windows native threads. Used by the cpool example only; we could keep this code inline there, but it's really just unimportant details. Copyright (c) 2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_THREADS_H) #define MYSQLPP_THREADS_H #include <mysql++.h> #if defined(MYSQLPP_PLATFORM_WINDOWS) # define HAVE_THREADS # define CALLBACK_SPECIFIER WINAPI typedef DWORD thread_return_t; typedef LPVOID thread_arg_t; static int create_thread(LPTHREAD_START_ROUTINE worker, thread_arg_t arg) { return CreateThread(0, 0, worker, arg, 0, 0) ? 0 : GetLastError(); } static void sleep(int s) { Sleep(s * 1000); } #else # include "../config.h" # if defined(HAVE_UNISTD_H) # include <unistd.h> # endif # if defined(HAVE_PTHREAD) # define HAVE_THREADS # define CALLBACK_SPECIFIER typedef void* thread_return_t; typedef void* thread_arg_t; static int create_thread(thread_return_t(*worker)(thread_arg_t), thread_arg_t arg) { pthread_t pt; return pthread_create(&pt, 0, worker, arg); } # endif #endif #endif // !defined(MYSQLPP_THREADS_H) |
Added examples/tquery1.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 | /*********************************************************************** tquery1.cpp - Example similar to ssqls3.cpp, except that it uses template queries instead of SSQLS. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Build a template query to retrieve a stock item given by // item name. mysqlpp::Query query = con.query( "select * from stock where item = %0q"); query.parse(); // Retrieve an item added by resetdb; it won't be there if // tquery* or ssqls3 is run since resetdb. mysqlpp::StoreQueryResult 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(); // forget previous template query data query << "update stock set item = %0q where item = %1q"; query.parse(); mysqlpp::SimpleResult res2 = query.execute("Nuerenberger Bratwurst", res1[0][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; } |
Added examples/tquery2.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 | /*********************************************************************** tquery2.cpp - Same as tquery1.cpp, except that it passes the template query parameters in a SQLQueryParms object, instead of separately. This is useful when the calling code doesn't know in advance how many parameters there will be. This is most likely because the templates are coming from somewhere else, or being generated. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Build a template query to retrieve a stock item given by // item name. mysqlpp::Query query = con.query( "select * from stock where item = %0q"); query.parse(); // Retrieve an item added by resetdb; it won't be there if // tquery* or ssqls3 is run since resetdb. mysqlpp::SQLQueryParms sqp; sqp << "Nürnberger Brats"; mysqlpp::StoreQueryResult res1 = query.store(sqp); 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(); // forget previous template query info query << "update stock set item = %0q where item = %1q"; query.parse(); sqp.clear(); sqp << "Nuerenberger Bratwurst" << res1[0][0].c_str(); mysqlpp::SimpleResult res2 = query.execute(sqp); // 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; } |
Added examples/tquery3.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 | /*********************************************************************** tquery3.cpp - Similar to tquery1.cpp but uses unquoted parameters. It's here more for code test coverage than because it shows something interesting. We've historically had a problem with tqueries with just one parameter; we cover the quoted case in resetdb and the other tquery examples, so we get the unquoted one here. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Build a template query to retrieve item names for stock // entries with a quantity over some threshold. mysqlpp::Query query = con.query( "select item from stock where num > %0"); query.parse(); // Get a list of things we have lots of in stock if (mysqlpp::StoreQueryResult res = query.store(80)) { cout << "Stuff we have a lot of in stock:" << endl; for (size_t i = 0; i < res.num_rows(); ++i) { cout << '\t' << res[i]["item"] << endl; } } else { cerr << "Failed to get item list: " << query.error() << endl; return 1; } } catch (const mysqlpp::BadQuery& er) { // Handle any query errors cerr << "Query error: " << er.what() << endl; return 2; } catch (const mysqlpp::Exception& er) { // Catch-all for any other MySQL++ exceptions cerr << "Error: " << er.what() << endl; return 2; } return 0; } |
Added examples/tquery4.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 | /*********************************************************************** tquery4.cpp - Tests other details about template queries, like unquoted parameters, multiple parameters, and preventing problems with LIKE patterns. This exists more for code coverage than to demonstrate the library. Copyright (c) 2009 by Martin Gallwey and (c) 2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include <iostream> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // Modify an item using two named template query parameters mysqlpp::Query query = con.query("update stock " "set num = %0:quantity where num < %0:quantity"); query.parse(); query.template_defaults["quantity"] = 70; cout << "Query: " << query << endl; mysqlpp::SimpleResult result = query.execute(); // Print the new table contents. print_stock_table(query); // Now let's check multiple dissimilar parameter types, and show // how to avoid conflicts between '%' as used in tqueries vs in // LIKE patterns. query.reset(); query << "select * from stock where weight > %0q or " "description like '%%%1%%'"; query.parse(); cout << "\nQuery: " << query.str(1.2, "Mustard") << endl; mysqlpp::StoreQueryResult res = query.store(1.2, "Mustard"); // Show what second tquery found 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/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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | /*********************************************************************** transaction.cpp - Example showing how to use MySQL++'s transaction features. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include "printdata.h" #include "stock.h" #include <iostream> #include <cstdio> using namespace std; int main(int argc, char *argv[]) { // Get database access parameters from command line mysqlpp::examples::CommandLine cmdline(argc, argv); if (!cmdline) { return 1; } try { // Establish the connection to the database server. mysqlpp::Connection con(mysqlpp::examples::db_name, cmdline.server(), cmdline.user(), cmdline.pass()); // 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 { // Use a higher level of transaction isolation than MySQL // offers by default. This trades some speed for more // predictable behavior. We've set it to affect all // transactions started through this DB server connection, // so it affects the next block, too, even if we don't // commit this one. mysqlpp::Transaction trans(con, mysqlpp::Transaction::serializable, mysqlpp::Transaction::session); stock row("Sauerkraut", 42, 1.2, 0.75, mysqlpp::sql_date("2006-03-06"), mysqlpp::null); query.insert(row); query.execute(); cout << "\nRow 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 { // Start a new transaction, keeping the same isolation level // we set above, since it was set to affect the session. mysqlpp::Transaction trans(con); cout << "\nNow adding catsup to the database..." << endl; stock row("Catsup", 3, 3.9, 2.99, mysqlpp::sql_date("2006-03-06"), mysqlpp::null); query.insert(row); query.execute(); } 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 examples/updel.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/usequery.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/util.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted examples/util.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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.txt 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; } |
Added 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.txt 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(); }; |
Added 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 |
Added 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 | /*********************************************************************** 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.txt 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::StoreQueryResult res = query.store(); if (res) { // Display the result set for (size_t i = 0; i < res.num_rows(); ++i) { if (ToUCS2(awcTempBuf, kTempBufSize, res[i][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())) { 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; } } |
Added 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.txt 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() }; |
Added 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 |
Added 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.txt 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 |
Added 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)]; |
Added 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 | /*********************************************************************** 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.txt 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::StoreQueryResult res = query.store(); if (res) { // Display the result set for (size_t i = 0; i < res.num_rows(); ++i) { AddMessage(ToUCS2(res[i][0])); } // Retreive was successful, so save user inputs now SaveInputs(); } else { // Retreive failed AddMessage("Failed to get item list:"); AddMessage(ToUCS2(query.error())); } } // 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 }; } |
Added 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> |
Added examples/vstudio/wforms/resource.h.
> > > | 1 2 3 | //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by app.rc |
Added 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; } |
Added 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 55 56 57 58 59 60 61 62 63 64 65 66 | #!/bin/sh if [ -z "$1" ] then echo "usage: $0 [TOOL] <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 " TOOL can be 'valgrind', 'gdb', or 'ldd', which causes exrun to" echo " run the example program under the given tool." 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 elif [ "$PROG" = 'ldd' ] then TOOL='ldd' shift PROG=$1 fi shift if [ -e "$PROG" ] then if [ `uname -s` = 'Darwin' ] then DYLD_LIBRARY_PATH=. $TOOL ./$PROG $* elif [ `uname -o` = 'Cygwin' ] then # Cygwin build case; see below for bash-as-DOS-shell case PATH=. $TOOL ./$PROG $* elif [ -e /usr/bin/ldd ] then if [ `uname -s` = 'SunOS' ] then LD_LIBRARY_PATH=.:/usr/mysql/lib/mysql $TOOL ./$PROG $* else LD_LIBRARY_PATH=. $TOOL ./$PROG $* fi else echo "ERROR: I don't grok this system's dynamic linkage system." fi elif [ `uname -o` = 'Cygwin' ] then # VC++ build, but using Cygwin's bash as shell to run programs cmd.exe /c exrun.bat $PROG $* else echo "usage: $0 [TOOL] <example> [args...]" echo echo " Run $0 without arguments for more detailed usage info." echo exit 1 fi |
Added exrun.bat.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @echo off set PROG=%1 if not exist %PROG% set PROG=%1.exe if not exist %PROG% set PROG=Debug\%1 if not exist %PROG% set PROG=vc2008\x64\Debug\%1.exe if not exist %PROG% set PROG=vc2008\Debug\%1.exe if not exist %PROG% set PROG=vc2005\Debug\%1.exe if not exist %PROG% set PROG=vc2003\Debug\%1.exe if not exist %PROG% exit shift set PATH=Debug;vc2008\x64\Debug;vc2008\Debug;vc2005\Debug;vc2003\Debug;%PATH% echo Running %PROG%... %PROG% %1 %2 %3 %4 %5 %6 %7 %8 %9 |
Added install.hta.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 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- install.hta - GUI installer for Windows systems, using Microsoft's HTML Application technology. Tested on XP with IE7. May work on systems as old as Win9x with IE4. For all other platforms, use "make install". Copyright (c) 2008 by Educational Technology Resources, Inc. and Warren Young. Others may also hold copyrights on code in this file. See the CREDITS file in the top folder 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 --> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Install MySQL++ Development Files</title> <hta:application applicationname="mysqlppInstaller" borderstyle="raised" innerborder="no" scroll="no" singleinstance="yes" sysmenu="no"/> <style type="text/css"> body { background-color: buttonface; margin: 10px; } body, button, input, select, td { font-family: Trebuchet MS, Helvetica; font-size: 10pt; } input.status { background-color: buttonface; border: none; } </style> <script type="text/javascript"> function $(id) { return document.getElementById(id); } </script> <script type="text/javascript"> var c = ''; var fso = new ActiveXObject('Scripting.FileSystemObject'); var folderList, driveList, installTargetField, segregateManagedBox, segregatePlatformBox, versionedFolderBox; var managedBuild = false; // Copies a file under a given prefix folder to another folder // given as a subfolder under some fixed prefix folder, // creating the whole folder path if needed, if it doesn't exist. // Skips prefix prepending if prefix is null. Skips folder // creation if source file doesn't exist. function copyFile(filePrefix, file, dirPrefix, destSubDir) { var src = filePrefix ? fso.BuildPath(filePrefix, file) : file; if ((!filePrefix || fso.FolderExists(filePrefix)) && ((src.indexOf('*') != -1) || fso.FileExists(src))) { var dst = createFolderRecursive( dirPrefix ? fso.BuildPath(dirPrefix, destSubDir) : destSubDir); try { fso.CopyFile(src, dst); } catch (e) { alert('Failed to copy ' + file + ' to ' + baseInstallFolder + ': ' + e.message + '\n\nInstallation aborted!'); window.close(); } } } // Creates a folder if it doesn't already exist. If creation // attempt fails, puts up alert dialog explaining the problem and // quits program. function createFolder(d) { if (!fso.FolderExists(d)) { try { fso.CreateFolder(d); } catch (e) { alert('Failed to create ' + d + ' folder: ' + e.message + '\n\nInstallation aborted!'); window.close(); } } } // Like createFolder(), but will create parent directories as // needed. Returns d, normalized. function createFolderRecursive(d) { var i, dir = '', dirElements = d.split('\\'); for (i = 0; i < dirElements.length; ++i) { dir += dirElements[i] + '\\'; createFolder(dir); } return dir; } // Called when app is fully loaded, so initialize ourselves. function init() { // Set initial window size window.resizeTo(600, 390); // Get references to main UI elements folderList = $('folder'); driveList = $('drive'); installTargetField = $('installTarget'); segregateManagedBox = $('segregateManaged'); segregatePlatformBox = $('segregatePlatform'); versionedFolderBox = $('versionedFolder'); // Populate drop-down list of available drives populateDriveList(); // Populate list of directories on the current drive populateFolderList(); // Now that we have drive and folder lists, set initial value // for installation folder from default list selections. updateInstallFolder(); // Set up UI event handlers. We put it off to this point so // UI is populated before first handler gets called. driveList.onchange = function() { populateFolderList(); updateInstallFolder(); } folderList.onchange = segregateManagedBox.onclick = versionedFolderBox.onclick = updateInstallFolder; } // Do the actual installation function install() { var i, destSubDir, srcDir; var usePlatform = segregatePlatformBox.checked; var versions = [ '3', '5', '8' ], version; // Install header files copyFile('lib', '*.h', baseInstallFolder, 'include'); // Install MinGW library build, if it exists destSubDir = 'lib' + (usePlatform ? '\\MinGW' : ''); copyFile(null, 'libmysqlpp.a', baseInstallFolder, destSubDir); copyFile(null, 'mysqlpp.dll', baseInstallFolder, destSubDir); // Install any and all existing VC++ library builds for (i = 0; i < versions.length; ++i) { version = 'vc200' + versions[i]; destSubDir = 'lib' + (usePlatform ? '\\VC++ 200' + versions[i] : ''); if (segregateManagedBox.checked) { destSubDir += '\\' + (isManagedBuild(version) ? 'CLR' : 'Native'); } srcDir = version + '\\Debug'; copyFile(srcDir, 'mysqlpp_d.dll', baseInstallFolder, destSubDir); copyFile(srcDir, 'mysqlpp_d.lib', baseInstallFolder, destSubDir); srcDir = version + '\\Release'; copyFile(srcDir, 'mysqlpp.dll', baseInstallFolder, destSubDir); copyFile(srcDir, 'mysqlpp.lib', baseInstallFolder, destSubDir); } window.close(); } // Returns true if the MySQL++ library for the given VC++ // version was built for use with the CLR. function isManagedBuild(version) { var stream = fso.OpenTextFile( version + '\\mysql++_mysqlpp.vcproj'); if (stream) { var mloc = stream.ReadAll().indexOf('ManagedExtensions="1"'); stream.Close(); return mloc > 0; } else { return false; } } // Populates a drop-down list with the set of fixed disks and // removable drives with media in them. function populateDriveList() { var defLetter = 'C'; var e, i, letter, name; for (e = new Enumerator(fso.Drives); !e.atEnd(); e.moveNext()) { i = e.item(); if (i.IsReady) { letter = i.DriveLetter; name = letter + ': - '; if ((i.DriveType == 3) && i.ShareName.length) { name += i.ShareName; } else if ((i.DriveType != 3) && i.VolumeName.length) { name += i.VolumeName; } else { name += '(no name)'; } driveList.add(new Option(name, letter, letter == defLetter, letter == defLetter)); } } } // Populates a list box with the top-level directories on the // currently-selected disk drive. function populateFolderList() { var driveRoot = driveList.options[driveList.selectedIndex].value + ':\\'; var e, f = fso.GetFolder(driveRoot); if (f) { folderList.options.length = 0; folderList.add(new Option(driveRoot, driveRoot, true, true)); for (e = new Enumerator(f.SubFolders); !e.atEnd(); e.moveNext()) { folderList.add(new Option(e.item() + '\\')); } } else { alert('Failed to get folder list for ' + driveRoot); } } // On clicking the text label associated with "versioned install // folder" checkbox, toggle checkbox and update UI. function toggleVersioning() { if (versionedFolderBox) { versionedFolderBox.checked = !versionedFolderBox.checked; updateInstallFolder(); } } // On clicking the text label associated with a checkbox, toggle // checkbox state and update UI. function toggleCheckbox(boxID) { var box = $(boxID); if (box) { box.checked = !box.checked; updateInstallFolder(); } } // Called any time something changes that affects how we calculate // the installation folder name. Rebuilds it. function updateInstallFolder() { baseInstallFolder = folderList.options[folderList.selectedIndex].text + 'MySQL++' + (versionedFolderBox.checked ? '\\@PACKAGE_VERSION@' : ''); installTargetField.value = baseInstallFolder + '\\{include,lib' + (segregatePlatformBox.checked ? '\\PLATFORM' : '') + (segregateManagedBox.checked ? '\\{CLR,Native}' : '') + '}'; } </script> </head> <body onload="init()"> <p> Where would you like to install the MySQL++ development files?<br/> <table cellspacing="10" cellpadding="0" border="0" width="100%" summary=""> <tr> <td align="right" valign="middle">Drives:</td> <td width="99%"> <select id="drive"> </select> </td> </tr> <tr> <td align="right" valign="top">Folders:</td> <td width="99%"> <select id="folder" size="6"> </select> </td> </tr> <tr> <td> </td> <td> <input type="checkbox" id="versionedFolder"/> <span style="cursor: default" onclick="toggleCheckbox('versionedFolder')">Install in versioned folder?</span> </td> </tr> <tr> <td> </td> <td> <input type="checkbox" id="segregateManaged"/> <span style="cursor: default" onclick="toggleCheckbox('segregateManaged')">Segregate native C++ library builds from C++/CLI (CLR) builds?</span> </td> </tr> <tr> <td> </td> <td> <input type="checkbox" id="segregatePlatform"/> <span style="cursor: default" onclick="toggleCheckbox('segregatePlatform')">Segregate libraries by platform?</span> </td> </tr> <tr> <td align="right" valign="middle">Target:</td> <td valign="middle" width="99%"> <input type="text" readonly="readonly" class="status" id="installTarget" size="80"/> </td> </tr> <tr> <td colspan="2" align="center"> <button onclick="install()"> Install Now </button> <button onclick="window.close()"> Never Mind </button> </td> </tr> </table> <p> </body> </html> |
Changes to 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 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 | # Doxyfile 1.8.5 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single 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. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My 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@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. 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 causes # performance problems for the file system. # The default value is: NO. 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. # Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- # Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, # Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES 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. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES 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. # The default value is: YES. 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 and 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. # The default value is: NO. 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. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES 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 # The default value is: YES. FULL_PATH_NAMES = NO # 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. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. 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 list of 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. # The default value is: NO. 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-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_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 behavior. 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 behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. 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. # The default value is: NO. 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. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that act 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 = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # 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. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # 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); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # 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. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES 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. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # 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 respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. 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. Does not have any effect # for Java sources. # The default value is: YES. 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 only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO 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. # The default value is: NO. 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 these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. 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 these declarations will be # included in the documentation. # The default value is: NO. 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 these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. 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 then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. 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. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES 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. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = 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 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. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = 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. # The default value is: YES. 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. # The default value is: YES. 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. # The default value is: YES. 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. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if <section_label> ... \endif and \cond <section_label> # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have 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 value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. 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. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # 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. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. Do not use file names with spaces, bibtex cannot handle them. See # also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag 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. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag 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. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. 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) # The default value is: $file:$line: $text. 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 standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is 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. # Note: If this tag is empty the current directory is searched. 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. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. 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 patterns (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, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # 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. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = querydef.h \ ssqls.h \ ssqls2.cpp \ ssqls2.h # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. 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 # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */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. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be 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. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. 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 information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # 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 that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES 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 documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = 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. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES 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. # See also: Section \class. # The default value is: YES. 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. # The default value is: YES. ALPHABETICAL_INDEX = NO # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. 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 a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. 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. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. 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). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = ../doc/html/refman/_header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. 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 left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # 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. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # 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. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # 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). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # 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. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value 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 # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # 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. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use <access key> + S # (what the <access key> is depends on the OS and browser, but it is typically # <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down # key> to jump into the search results window, the results can be navigated # using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel # the search. The filter options can be selected when the cursor is inside the # search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> # to select a filter and <Enter> or <escape> to activate or cancel the filter # option. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There # are two flavours of web server based searching depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. See # the section "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # # Doxygen ships with an example indexer ( doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # # Doxygen ships with an example indexer ( doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. # The default file is: searchdata.xml. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of # to a relative location where the documentation can be found. The format is: # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO # 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. # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # # Note that when enabling USE_PDFLATEX this option is only used for generating # bitmaps for formulas in the HTML output, but not in the Makefile that is # written to the output directory. # The default file is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. 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. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. 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 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x # 14 inches) and executive (7.25 x 10.5 inches). # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # that should be included in the LaTeX output. To get the times font for # instance you can specify # EXTRA_PACKAGES=times # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. 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. See # section "Doxygen usage" for information on how to let doxygen write the # default header to a separate file. # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, # $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will # replace them by respectively the title of the page, the current date and time, # only the current date, the version number of doxygen, the project name (see # PROJECT_NAME), or the project number (see PROJECT_NUMBER). # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last # chapter. If it is left blank doxygen will generate a standard footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). 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. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. PDF_HYPERLINKS = NO # If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # the PDF file directly from the LaTeX files. Set this option to YES to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. 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. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BATCHMODE = NO # If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the # index chapters (such as File Index, Compound Index, etc.) in the output. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HIDE_INDICES = NO # If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source # code with syntax highlighting in the LaTeX output. # # Note that which sources are shown also depends on other settings such as # SOURCE_BROWSER. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # http://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # 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 too pretty with other RTF # readers/editors. # The default value is: NO. 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. # The default directory is: rtf. # This tag requires that the tag GENERATE_RTF is set to YES. 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. # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. 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 some other Word compatible readers that support those # fields. # # Note: WordPad (write) and others do not support links. # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. 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. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is # similar to doxygen's config file. A template extensions file can be generated # using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES doxygen will generate man pages for # classes and files. # The default value is: NO. 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. A directory man3 will be created inside the directory specified by # MAN_OUTPUT. # The default directory is: man. # This tag requires that the tag GENERATE_MAN is set to YES. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to the generated # man pages. In case the manual section does not start with a number, the number # 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is # optional. # The default value is: .3. # This tag requires that the tag GENERATE_MAN is set to YES. 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 value is: NO. # This tag requires that the tag GENERATE_MAN is set to YES. 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. # The default value is: NO. 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. # The default directory is: xml. # This tag requires that the tag GENERATE_XML is set to YES. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a # validating XML parser to check the syntax of the XML files. # This tag requires that the tag GENERATE_XML is set to YES. XML_SCHEMA = # The XML_DTD tag can be used to specify a XML DTD, which can be used by a # validating XML parser to check the syntax of the XML files. # This tag requires that the tag GENERATE_XML is set to YES. 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. # The default value is: YES. # This tag requires that the tag GENERATE_XML is set to YES. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- # If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in # front of it. # The default directory is: docbook. # This tag requires that the tag GENERATE_DOCBOOK is set to YES. DOCBOOK_OUTPUT = docbook #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen # Definitions (see http://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. # The default value is: NO. 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. # The default value is: NO. 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. # The default value is: NO. # This tag requires that the tag GENERATE_PERLMOD is set to YES. 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. # The default value is: YES. # This tag requires that the tag GENERATE_PERLMOD is set to YES. 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. # This tag requires that the tag GENERATE_PERLMOD is set to YES. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. 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 only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set 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. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES the includes files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 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. # This tag requires that the tag SEARCH_INCLUDES is set to YES. 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. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 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 e.g. # 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. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 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 that overrules the # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all refrences to 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. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration options related to external references #--------------------------------------------------------------------------- # The TAGFILES tag can be used to specify one or more tag files. For each tag # file the location of the external documentation should be added. 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. See the # section "Linking to external documentation" for more information about the use # of tag files. # Note: Each tag file must have an 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. See section "Linking to # external documentation" for more information about the usage of tag files. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external class will be listed in the # class index. If set to NO only the inherited external classes will be listed. # The default value is: NO. 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. # The default value is: YES. EXTERNAL_GROUPS = YES # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. EXTERNAL_PAGES = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of 'which perl'). # The default file (with absolute path) is: /usr/bin/perl. PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more # powerful graphs. # The default value is: YES. 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. # The default value is: YES. 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 (see: # http://www.graphviz.org/), 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 value is: NO. HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of # processors available in the system. You can set it explicitly to a value # larger than 0 to get control over the balance between CPU load and processing # speed. # Minimum value: 0, maximum value: 32, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. DOT_NUM_THREADS = 0 # When you want a differently looking font n the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by # setting DOT_FONTPATH to the directory containing the font. # The default value is: Helvetica. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size (in points) of the font of # dot graphs. # Minimum value: 4, maximum value: 24, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the default font as specified with # DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set # the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = # If the CLASS_GRAPH tag is 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 CLASS_DIAGRAMS tag to NO. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside the # class node. If there are many fields or methods and many nodes the graph may # become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the # number of items for each type to make the size more manageable. Set this to 0 # for no limit. Note that the threshold may be exceeded by 50% before the limit # is enforced. So when you set the threshold to 10, up to 15 fields may appear, # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. UML_LIMIT_NUM_FIELDS = 10 # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. TEMPLATE_RELATIONS = YES # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. CALL_GRAPH = NO # If the CALLER_GRAPH tag is 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). # Possible values are: png, jpg, gif and svg. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # # Note that this requires a modern browser other than Internet Explorer. Tested # and working are Firefox, Chrome, Safari, and Opera. # Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make # the SVG files visible. Older versions of IE do not have SVG support. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. INTERACTIVE_SVG = NO # The DOT_PATH tag 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. # This tag requires that the tag HAVE_DOT is set to YES. 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). # This tag requires that the tag HAVE_DOT is set to YES. DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). MSCFILE_DIRS = # The 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 if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. # Minimum value: 0, maximum value: 10000, default value: 50. # This tag requires that the tag HAVE_DOT is set to YES. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs # generated by dot. A depth value of 3 means that only nodes reachable from the # root by following a path via at most 3 edges will be shown. Nodes that lay # further from the root node will be omitted. Note that setting this option to 1 # or 2 may greatly reduce the computation time needed for large code bases. Also # note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. # Minimum value: 0, maximum value: 1000, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not seem # to support this out of the box. # # 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). # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES |
Deleted lib/Makefile.am.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.base.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.bc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.gcc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.in.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.mingw.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.simple.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/Makefile.vc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 58 59 60 61 | /// \file autoflag.h /// \brief Defines a template for setting a flag within a given variable /// scope, and resetting it when exiting that scope. /*********************************************************************** Copyright © 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 namespace mysqlpp { /// \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_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_AUTOFLAG_H) |
Added lib/beemutex.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 | /*********************************************************************** beemutex.cpp - Implements the BeecryptMutex class. The name comes from the fact that we lifted this essentially intact from the Beecrypt library, which is also LGPL. See beecrypt.h for the list of changes we made on integrating it into MySQL++. Copyright (c) 2004 Beeyond Software Holding BV and (c) 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "beemutex.h" #include "common.h" #include <errno.h> #include <string.h> namespace mysqlpp { #define ACTUALLY_DOES_SOMETHING #if defined(HAVE_PTHREAD) typedef pthread_mutex_t bc_mutex_t; #elif defined(HAVE_SYNCH_H) # include <synch.h> typedef mutex_t bc_mutex_t; #elif defined(MYSQLPP_PLATFORM_WINDOWS) typedef HANDLE bc_mutex_t; #else // No supported mutex type found, so class becomes a no-op. # undef ACTUALLY_DOES_SOMETHING #endif #if defined(ACTUALLY_DOES_SOMETHING) static bc_mutex_t* impl_ptr(void* p) { return static_cast<bc_mutex_t*>(p); } # if defined(MYSQLPP_PLATFORM_WINDOWS) static bc_mutex_t impl_val(void* p) { return *static_cast<bc_mutex_t*>(p); } # endif #endif BeecryptMutex::BeecryptMutex() throw (MutexFailed) #if defined(ACTUALLY_DOES_SOMETHING) : pmutex_(new bc_mutex_t) #endif { #if defined(MYSQLPP_PLATFORM_WINDOWS) *impl_ptr(pmutex_) = CreateMutex((LPSECURITY_ATTRIBUTES) 0, FALSE, (LPCTSTR) 0); if (!impl_val(pmutex_)) throw MutexFailed("CreateMutex failed"); #else # if HAVE_SYNCH_H || HAVE_PTHREAD register int rc; # endif # if HAVE_PTHREAD if ((rc = pthread_mutex_init(impl_ptr(pmutex_), 0))) throw MutexFailed(strerror(rc)); # elif HAVE_SYNCH_H if ((rc = mutex_init(impl_ptr(pmutex_), USYNC_THREAD, 0))) throw MutexFailed(strerror(rc)); # endif #endif } BeecryptMutex::~BeecryptMutex() { #if defined(ACTUALLY_DOES_SOMETHING) # if defined(MYSQLPP_PLATFORM_WINDOWS) CloseHandle(impl_val(pmutex_)); # elif HAVE_PTHREAD pthread_mutex_destroy(impl_ptr(pmutex_)); # elif HAVE_SYNCH_H mutex_destroy(impl_ptr(pmutex_)); # endif delete impl_ptr(pmutex_); #endif } void BeecryptMutex::lock() throw (MutexFailed) { #if defined(MYSQLPP_PLATFORM_WINDOWS) if (WaitForSingleObject(impl_val(pmutex_), INFINITE) == WAIT_OBJECT_0) return; throw MutexFailed("WaitForSingleObject failed"); #else # if HAVE_SYNCH_H || HAVE_PTHREAD register int rc; # endif # if HAVE_PTHREAD if ((rc = pthread_mutex_lock(impl_ptr(pmutex_)))) throw MutexFailed(strerror(rc)); # elif HAVE_SYNCH_H if ((rc = mutex_lock(impl_ptr(pmutex_)))) throw MutexFailed(strerror(rc)); # endif #endif } bool BeecryptMutex::trylock() throw (MutexFailed) { #if defined(ACTUALLY_DOES_SOMETHING) # if defined(MYSQLPP_PLATFORM_WINDOWS) switch (WaitForSingleObject(impl_val(pmutex_), 0)) { case WAIT_TIMEOUT: return false; case WAIT_OBJECT_0: return true; default: throw MutexFailed("WaitForSingleObbject failed"); } # else register int rc; # if HAVE_PTHREAD if ((rc = pthread_mutex_trylock(impl_ptr(pmutex_))) == 0) return true; if (rc == EBUSY) return false; throw MutexFailed(strerror(rc)); # elif HAVE_SYNCH_H if ((rc = mutex_trylock(impl_ptr(pmutex_))) == 0) return true; if (rc == EBUSY) return false; throw MutexFailed(strerror(rc)); # endif # endif #else return true; // no-op build, so always succeed #endif } void BeecryptMutex::unlock() throw (MutexFailed) { #if defined(MYSQLPP_PLATFORM_WINDOWS) if (!ReleaseMutex(impl_val(pmutex_))) throw MutexFailed("ReleaseMutex failed"); #else # if HAVE_SYNCH_H || HAVE_PTHREAD register int rc; # endif # if HAVE_PTHREAD if ((rc = pthread_mutex_unlock(impl_ptr(pmutex_)))) throw MutexFailed(strerror(rc)); # elif HAVE_SYNCH_H if ((rc = mutex_unlock(impl_ptr(pmutex_)))) throw MutexFailed(strerror(rc)); # endif #endif } } // end namespace mysqlpp |
Added lib/beemutex.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 | /// \file beemutex.h /// \brief MUTually EXclusive lock class. /// \author Bob Deblier <bob.deblier@telenet.be> /// /// Modified by Warren Young of Educational Technology Resources, Inc. /// from version in Beecrypt 4.1.2: /// /// - minor style changes to make it fit within MySQL++ /// - changed init() to a ctor and destroy() to a dtor /// - class just becomes a no-op if no supported mutex type is available /// - throwing MutexFailed instead of \c char* /// - moved all method implementations from inline in the .h file to /// a .cpp file so we don't have to make the header depend on config.h /// on autoconf-using systems /// - made private mutex member a void* so we don't have to define the /// full type in the .h file, due to previous item /// - added more Doxygen comments, and changed some existing comments /*********************************************************************** Copyright (c) 2004 Beeyond Software Holding BV and (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_BEEMUTEX_H) #define MYSQLPP_BEEMUTEX_H #include "exceptions.h" namespace mysqlpp { /// \brief Wrapper around platform-specific mutexes. /// /// This class is only intended to be used within the library. We don't /// really want to support this as a general purpose class. If it works /// for you as-is, that's great, we won't try to stop you. But if you /// run into a problem that doesn't affect MySQL++ itself, we're not /// likely to bother enhancing this class to fix the problem. class MYSQLPP_EXPORT BeecryptMutex { public: /// \brief Create the mutex object /// /// Throws a MutexFailed exception if we can't acquire the lock for /// some reason. The exception contains a message saying why. BeecryptMutex() throw (MutexFailed); /// \brief Destroy the mutex /// /// Failures are quietly ignored. ~BeecryptMutex(); /// \brief Acquire the mutex, blocking if it can't be acquired /// immediately. void lock() throw (MutexFailed); /// \brief Acquire the mutex immediately and return true, or return /// false if it would have to block to acquire the mutex. bool trylock() throw (MutexFailed); /// \brief Release the mutex void unlock() throw (MutexFailed); private: void* pmutex_; }; /// \brief Wrapper around BeecryptMutex to add scope-bound locking /// and unlocking. /// /// This allows code to lock a mutex and ensure it will unlock on exit /// from the enclosing scope even in the face of exceptions. This is /// separate from BeecryptMutex because we don't want to make this /// behavior mandatory. class ScopedLock { public: /// \brief Lock the mutex. explicit ScopedLock(BeecryptMutex& mutex) : mutex_(mutex) { mutex.lock(); } /// \brief Unlock the mutex. ~ScopedLock() { mutex_.unlock(); } private: ScopedLock(const ScopedLock&); // can't copy ScopedLock& operator =(const ScopedLock&); // can't assign BeecryptMutex& mutex_; ///< the mutex object we manage }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_BEEMUTEX_H) |
Added lib/cmdline.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 | /*********************************************************************** cmdline.cpp - Command line parsing stuff used by the example and utility programs. Not intended for end-user use! Copyright (c) 2007-2009 by Educational Technology Resources, Inc. getopt() and its associated globals are the public domain implementation made available at the 1985 UNIFORUM conference in Dallas, Texas; the code is untouched except for style tweaks. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cmdline.h" #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> //// getopt //////////////////////////////////////////////////////////// // Bring in system getopt(), or define our own. #if defined(HAVE_POSIX_GETOPT) # include <unistd.h> #elif defined(HAVE_LIBIBERTY_GETOPT) # include <libiberty.h> #else // Need to define our own getopt() on this system extern "C" { // Using C linkage to avoid potential conflicts with system // getopt(), if autoconf test fails to find it. static const char* optarg; static int optind = 1; static int getopt(int argc, char* const argv[], const char* opts) { static int optopt; static int sp = 1; register int c; register const char *cp; if (sp == 1) { /* If all args are processed, finish */ if (optind >= argc) { return EOF; } if (argv[optind][0] != '-' || argv[optind][1] == '\0') { return EOF; } } else if (!strcmp(argv[optind], "--")) { /* No more goptions to be processed after this one */ optind++; return EOF; } optopt = c = argv[optind][sp]; /* Check for invalid goption */ if (c == ':' || (cp = strchr(opts, c)) == 0) { fprintf(stderr, "%s: illegal option -- %c\n", argv[0], c); if (argv[optind][++sp] == '\0') { optind++; sp = 1; } return '?'; } /* Does this goption require an argument? */ if (*++cp == ':') { /* If so, get argument; if none provided output error */ if (argv[optind][sp + 1] != '\0') { optarg = &argv[optind++][sp + 1]; } else if (++optind >= argc) { fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0], c); sp = 1; return '?'; } else { optarg = argv[optind++]; } sp = 1; } else { if (argv[optind][++sp] == '\0') { sp = 1; optind++; } optarg = 0; } return c; } } // end extern "C" #endif // didn't find either POSIX or libiberty getopt() //////////////////////////////////////////////////////////////////////// // Generic MySQL++-specific command line parsing mechanism namespace mysqlpp { //// CommandLineBase::finish_parse ///////////////////////////////////// // Called by subclass when it's finished parsing the command line. It // does nothing if we're not still in a "successful" state. void CommandLineBase::finish_parse() { if (successful_) { const int nextras = argc_ - option_index(); if (nextras > 0) { extra_args_.resize(nextras); for (int i = 0; i < nextras; ++i) { extra_args_[i] = argv_[option_index() + i]; } } } } //// CommandLineBase::option_argument ////////////////////////////////// // Accessor for optarg, so caller doesn't have to know about this // getopt() style interface. Particualy helpful on non-POSIX systems. const char* CommandLineBase::option_argument() const { return optarg; } //// CommandLineBase::option_index ///////////////////////////////////// // Accessor for optind, so caller doesn't have to know about this // getopt() style interface. Particuarly helpful on non-POSIX systems. int CommandLineBase::option_index() const { return optind; } //// CommandLineBase::parse_next /////////////////////////////////////// // Wrapper around getopt(), using the stuff passed to our ctor to // construct its argument list. int CommandLineBase::parse_next() const { return getopt(argc_, argv_, opts_); } //// CommandLineBase::parse_error ////////////////////////////////////// // Called by subclasses when they encounter an error in parsing. We // wrap up several details of handling that error: display the // message on stderr, call the subclass's print_usage() method, and // marks the object as no longer successful. void CommandLineBase::parse_error(const char* message) { if (message) { std::cerr << message << '\n'; } print_usage(); successful_ = false; } //////////////////////////////////////////////////////////////////////// // Command line parser for MySQL++ examples. namespace examples { const char* db_name = "mysql_cpp_data"; //// examples::CommandLine ctor //////////////////////////////////////// CommandLine::CommandLine(int argc, char* const argv[], const char* user, const char* pass, const char* usage_extra) : CommandLineBase(argc, argv, "hm:p:s:u:D?"), dtest_mode_(false), run_mode_(0), server_(0), user_(user && *user ? user : 0), pass_(pass && *pass ? pass : ""), usage_extra_(usage_extra) { int ch; while (successful() && ((ch = parse_next()) != EOF)) { switch (ch) { case 'm': run_mode_ = atoi(option_argument()); break; case 'p': pass_ = option_argument(); break; case 's': server_ = option_argument(); break; case 'u': user_ = option_argument(); break; case 'D': dtest_mode_ = true; break; default: parse_error(); return; } } finish_parse(); } //// examples::CommandLine::print_usage //////////////////////////////// // Show a generic usage message suitable for ../examples/*.cpp The // parameters specialize the message to a minor degree. void CommandLine::print_usage(const char* extra) const { std::cout << "usage: " << program_name() << " [-s server_addr] [-u user] [-p password] " << (extra ? extra : "") << std::endl; std::cout << std::endl; std::cout << " If no options are given, connects to database " "server on localhost" << std::endl; std::cout << " using your user name and no password." << std::endl; if (extra && (strlen(extra) > 0)) { std::cout << std::endl; std::cout << " The extra parameter " << extra << " is required, regardless of which" << std::endl; std::cout << " other arguments you pass." << std::endl; } std::cout << std::endl; } } // end namespace mysqlpp::examples //////////////////////////////////////////////////////////////////////// // Command line parser for MySQL++'s ssqlsxlat tool. namespace ssqlsxlat { //// ssqlsxlat::CommandLine ctor //////////////////////////////////////// CommandLine::CommandLine(int argc, char* const argv[]) : CommandLineBase(argc, argv, "hi:o:p:s:t:u:1:?"), input_(0), output_(0), pass_(""), server_(0), user_(0), input_source_(ss_unknown), output_sink_(ss_unknown) { // Parse the command line int ch; while (successful() && ((ch = parse_next()) != EOF)) { switch (ch) { case 'i': case 't': case '1': if (input_) { std::cerr << "Warning: overriding previous input " "source! Only last -i, -t or -1 is " "effective.\n"; } input_ = option_argument(); input_source_ = (ch == '1' ? ss_ssqls1 : ch == 'i' ? ss_ssqls2 : ss_table); break; case 'o': output_ = option_argument(); output_sink_ = ss_ssqls2; break; case 'p': pass_ = option_argument(); break; case 's': server_ = option_argument(); break; case 'u': user_ = option_argument(); break; default: parse_error(); } } finish_parse(); // Figure out whether command line makes sense, and if not, tell // user about it. if (successful()) { if (input_source_ == ss_unknown) { parse_error("No input source given! Need -i, -t or -1."); } else if ((input_source_ != ss_ssqls2) && !output_) { parse_error("Need -o if you give -t or -1!"); } } } //// ssqlsxlat::CommandLine::print_usage //////////////////////////////// // Show a generic usage message suitable for ../ssqlsxlat/*.cpp The // parameters specialize the message to a minor degree. void CommandLine::print_usage() const { std::cerr << "usage: " << program_name() << " [ -i input.ssqls ] [ -1 input-ssqlsv1.cpp ]\n" " [ -u user ] [ -p password ] [ -s server ] [ -t table ]\n" " [ -o parsedump.ssqls ]\n"; std::cerr << std::endl; std::cerr << " -i: parse SSQLSv2 DSL, generating C++ output at minimum\n" " -o: write out .ssqls file containing info found by\n" " processing -i, -t or -1\n" " -u,p,s,t: log into server with given creds, get schema details\n" " for a table, and generate output as if parsed from\n" " SSQLSv2 DSL; requires -o\n" " -1: find SSQLSv1 declarations in C++ code, and try to\n" " interpret as equivalent SSQLSv2; requires -o\n" " -?,h: write out .ssqls file containing info found by\n" " processing -i, -t or -1\n"; std::cerr << std::endl; } } // end namespace mysqlpp::ssqlsxlat } // end namespace mysqlpp |
Added lib/cmdline.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 | /*********************************************************************** cmdline.h - Declares the interface to the MySQL++'s command line parsing logic, used by the examples and the utility programs. Not intended for use by third parties! If it breaks, you get to keep all the pieces. Copyright (c) 2007-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_CMDLINE_H) #define MYSQLPP_CMDLINE_H #include "common.h" #include <string> #include <vector> #include <assert.h> namespace mysqlpp { /// \brief Parses command line arguments and holds the results. /// /// This class just contains common functionality and data /// structures; instantiable subclasses follow. class MYSQLPP_EXPORT CommandLineBase { public: //// Public types /// \brief Type for a list of arguments typedef std::vector<std::string> ArgumentList; /// \brief Iterator into ArgumentList typedef ArgumentList::const_iterator ArgumentListIt; //// Public interface /// \brief Get reference to list of command line arguments past /// the last flag and its possible argument. const ArgumentList& extra_args() const { return extra_args_; } /// \brief Return truthy value if command line was parsed /// successfully operator void*() const { return successful_ ? const_cast<bool*>(&successful_) : 0; } protected: //// Subclass interface /// \brief Hidden ctor to prevent instantiation CommandLineBase(int argc, char* const argv[], const char* opts) : argc_(argc), argv_(argv), opts_(opts), successful_(argc > 0 && argv && opts) { assert(successful_); } /// \brief Hidden dtor to prevent instantiation virtual ~CommandLineBase() { } /// \brief If object is still marked as "successful", save /// non-option arguments to extra_args_ list. Subclass ctor /// should call this after the parse_next() loop gets EOF. void finish_parse(); /// \brief Accessor for getopt()'s optarg global const char* option_argument() const; /// \brief Accessor for getopt()'s optind global int option_index() const; /// \brief Called by a subclass when encountering a command /// line parsing error. /// /// Prints the passed message, calls subclass's print_usage(), /// and marks the object as no longer successful. void parse_error(const char* message = 0); /// \brief Wrapper for getopt() int parse_next() const; /// \brief Show a message explaining the program's proper usage virtual void print_usage() const = 0; /// \brief Get the file name of the program's executable const char* program_name() const { return argv_[0]; } /// \brief Returns true if nothing has gone wrong since calling /// the ctor. bool successful() const { return successful_; } private: //// Internal data int argc_; char* const* argv_; const char* opts_; bool successful_; ArgumentList extra_args_; }; /// \brief Stuff related to MySQL++ examples specifically namespace examples { /// \brief Name of examples' DB extern MYSQLPP_EXPORT const char* db_name; /// \brief Command line parsing mechanism for ../examples/*.cpp class MYSQLPP_EXPORT CommandLine : public CommandLineBase { public: //// Public interface /// \brief Constructor CommandLine(int argc, char* const argv[], const char* user = 0, const char* pass = 0, const char* usage_extra = 0); /// \brief Show a message explaining the program's proper usage /// /// Calls print_usage(const char*), passing along the /// "usage_extra" parameter passed to the ctor void print_usage() const { print_usage(usage_extra_); } /// \brief Show a message explaining the program's proper /// usage, with custom extra info after standard command /// line usage bits. void print_usage(const char* extra) const; /// \brief Return true if we're in "dtest" mode /// This happens when an example gets the -D flag, always /// passed by the dtest script to ask the programs it runs /// to suppress any nondeterministic output. bool dtest_mode() const { return dtest_mode_; } /// \brief Return the DB password (-p argument) const char* pass() const { return pass_; } /// \brief Return the -m flag value /// /// This flag is currently only used by examples/deadlock, /// but it's really a nonspecific "mode" value, which could /// be used by other examples in the future. int run_mode() const { return run_mode_; } /// \brief Return the DB server name (-s argument) const char* server() const { return server_; } /// \brief Return the DB user name (-u argument) const char* user() const { return user_; } private: //// Internal data // Examples-specific command line parse results bool dtest_mode_; int run_mode_; const char* server_; const char* user_; const char* pass_; const char* usage_extra_; }; } // end namespace mysqlpp::examples /// \brief Stuff specific to the ssqlsxlat tool namespace ssqlsxlat { /// \brief Command line parser for MySQL++'s ssqlsxlat tool class MYSQLPP_EXPORT CommandLine : public CommandLineBase { public: //// Public types /// \brief Types of inputs that ssqlsxlat will accept enum SourceSink { ss_unknown, ///< no known input type given yet ss_ssqls1, ///< a C++ file containing an SSQLS v1 declaration ss_ssqls2, ///< an SSQLS v2 file ss_table ///< an existing DB table schema }; //// Public interface /// \brief Constructor CommandLine(int argc, char* const argv[]); /// \brief Show a message explaining the program's proper usage void print_usage() const; /// \brief Return the name of the input source /// /// This can be a file name, a table name, etc. Call /// input_source() to determine the proper interpretation. const char* input() const { return input_; } /// \brief The input source type SourceSink input_source() const { return input_source_; } /// \brief The output sink (destination) type SourceSink output_sink() const { return output_sink_; } /// \brief The base name of the output file const char* output() const { return output_; } /// \brief DB password, when input type is is_table const char* pass() const { return pass_; } /// \brief DB server name, when input type is is_table const char* server() const { return server_; } /// \brief DB user name, when input type is is_table const char* user() const { return user_; } private: //// Internal data: command line parse results const char* input_; const char* output_; const char* pass_; const char* server_; const char* user_; SourceSink input_source_; SourceSink output_sink_; }; } // end namespace mysqlpp::ssqlsxlat } // end namespace mysqlpp #endif // !defined(MYSQLPP_CMDLINE_H) |
Deleted lib/coldata.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/coldata.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 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 | /// \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-2001 by MySQL AB, (c) 2004-2009 by Educational Technology Resources, Inc., and (c) 2009 by Warren Young. Others may also hold copyrights on code in this file. See the CREDITS.txt 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. // Enable SSQLS by default. Turned off below on platforms where we // know it doesn't work. #define MYSQLPP_SSQLS_COMPATIBLE // For all platforms but Visual C++ 2003, the following macro is just // an alias for "*this". It needs a more complicated definition on // VC++ 2003 to work around an error in the overloaded operator lookup // logic. For an explanation of the problem, see: // http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15 #define MYSQLPP_QUERY_THISPTR *this // 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. // Don't let windows.h (via Connector/C) #define min/max #define NOMINMAX // Stuff for Visual C++ only # if defined(_MSC_VER) # define MYSQLPP_PLATFORM_VISUAL_CPP // MS *still* doesn't ship stdint.h, through VC++ 2008 at least. // This means we have to take a wild guess at appropriate // integer types in lib/sql_types.h. See test/inttypes.cpp for // tests that check whether we've guessed well. # define MYSQLPP_NO_STDINT_H # if _MSC_VER < 1400 // Workarounds for limitations of VC++ 2003 that are fixed // in 2005 and later. # undef MYSQLPP_QUERY_THISPTR # define MYSQLPP_QUERY_THISPTR dynamic_cast<std::ostream&>(*this) # undef MYSQLPP_SSQLS_COMPATIBLE # elif !defined(_STLP_VERSION) && !defined(_STLP_VERSION_STR) // VC++ 2005 or newer and not using STLport, so #define // portability flags indicating features we can use from // the compiler's native RTL. # define MYSQLPP_HAVE_LOCALTIME_S # define MYSQLPP_HAVE_STD__NOINIT # endif // Disable complaints about STL data members: VC++ believes // these need to be __declspec(dllexport) for some reason. # pragma warning(disable: 4251) // Disable complaint that VC++ doesn't grok throw specs # pragma warning(disable: 4290) // 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) // Prior to Visual C++ 2015, we must use _snprintf() # if _MSC_VER < 1900 # define snprintf _snprintf # endif # 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 // We need to use the DOS/Windows path separator here #define MYSQLPP_PATH_SEPARATOR '\\' #else // If not VC++, MinGW, or Xcode, we assume we're on a system using // autoconf, so bring in the config.h file it wrote containing the // config test results. Only do this during the library build, and // even then, not if included from a MySQL++ header file, since // config.h cannot be safely installed with the other headers. # if defined(MYSQLPP_NOT_HEADER) && !defined(MYSQLPP_XCODE) # include "config.h" # endif // Make DLL stuff a no-op on this platform. #define MYSQLPP_EXPORT // Assume POSIX path separator #define MYSQLPP_PATH_SEPARATOR '/' #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(MYSQLPP_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 MYSQLPP_NO_LONG_LONGS. typedef unsigned long long ulonglong; typedef long long longlong; #endif #endif // !defined(DOXYGEN_IGNORE) #if !defined(MYSQLPP_NO_UNSIGNED_INT_TYPES) /// \brief Contraction for 'unsigned long' /// /// This is not to be used within the library or directly by end-user /// code. It exists to make the MySQL C API headers happy: my_global.h /// defines it, but we can't use it in MySQL++, so we do it ourselves. 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 #endif // !defined(MYSQLPP_COMMON_H) |
Added lib/comparable.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 | /// \file comparable.h /// \brief Declares the Comparable<T> mixin /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_COMPARABLE_H) #define MYSQLPP_COMPARABLE_H namespace mysqlpp { /// \brief Mix-in that gives its subclass a full set of comparison /// operators. /// /// Simply by inheriting publically from this and implementing /// compare(), the subclass gains a full set of comparison operators, /// because all of the operators are implemented in terms of compare(). template <class T> class Comparable { public: /// \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; } protected: /// \brief Destroy object /// /// This class has nothing to destroy, but declaring the dtor /// virtual placates some compilers set to high warning levels. /// Protecting it ensures you can't delete subclasses through base /// class pointers, which makes no sense because this class isn't /// made for polymorphism. It's just a mixin. virtual ~Comparable() { } /// \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. virtual int compare(const T& other) const = 0; }; } #endif // !defined(MYSQLPP_COMPARABLE_H) |
Deleted lib/compare.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/connection.cpp.
1 2 3 | /*********************************************************************** connection.cpp - Implements the Connection class. | | | | | < < > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < | | < < < > | < > | < < < | < < | > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < | | | < < | > > | < < < < | | > | < < < | < < < < | | < | > > > | < | < < < < < < < < | | < < < < < < < > > | > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > | > > | > > | | > > > > > | | < < > > > > > | > > > > > | < < < < < < < < | | < < < < | | | | < < < < < < < < | < | | < < < < < < < | | < < | < | < | < < | < < | < < < < < < < < < < < < < < < < < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < < | < < < < < < < | < < < < < < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < | < | 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 | /*********************************************************************** connection.cpp - Implements the Connection class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "connection.h" #include "dbdriver.h" #include "query.h" #include "result.h" using namespace std; namespace mysqlpp { Connection::Connection(bool te) : OptionalExceptions(te), driver_(new DBDriver()), copacetic_(true) { } Connection::Connection(const char* db, const char* server, const char* user, const char* password, unsigned int port) : OptionalExceptions(), driver_(new DBDriver()), copacetic_(true) { try { connect(db, server, user, password, port); } catch (...) { // Exception thrown from ctor causes dtor to not be called, so // we have to delete the DBDriver instance, else we'll leak it. delete driver_; throw; } } Connection::Connection(const Connection& other) : OptionalExceptions(other.throw_exceptions()), driver_(new DBDriver(*other.driver_)) { copy(other); } Connection::~Connection() { disconnect(); delete driver_; } void Connection::build_error_message(const char* core) { error_message_ = "Can't "; error_message_ += core; error_message_ += " while disconnected"; } std::string Connection::client_version() const { return driver_->client_version(); } bool Connection::connect(const char* db, const char* server, const char* user, const char* password, unsigned int port) { // Figure out what the server parameter means, then try to establish // the connection. error_message_.clear(); string host, socket_name; copacetic_ = parse_ipc_method(server, host, port, socket_name) && driver_->connect(host.c_str(), (socket_name.empty() ? 0 : socket_name.c_str()), port, db, user, password); // If it failed, decide how to tell the user if (!copacetic_ && throw_exceptions()) { throw ConnectionFailed(error(), errnum()); } else { return copacetic_; } } bool Connection::connected() const { return driver_->connected(); } void Connection::copy(const Connection& other) { error_message_.clear(); set_exceptions(other.throw_exceptions()); driver_->copy(*other.driver_); } ulonglong Connection::count_rows(const std::string& table) { error_message_.clear(); Query q(this, throw_exceptions()); q << "SELECT COUNT(*) FROM `" << table << '`'; if (StoreQueryResult res = q.store()) { return res[0][0]; } else { return 0; } } bool Connection::create_db(const std::string& db) { error_message_.clear(); Query q(this, throw_exceptions()); q << "CREATE DATABASE `" << db << '`'; return q.exec(); } void Connection::disconnect() { error_message_.clear(); driver_->disconnect(); } bool Connection::drop_db(const std::string& db) { error_message_.clear(); Query q(this, throw_exceptions()); q << "DROP DATABASE `" << db << '`'; return q.exec(); } int Connection::errnum() { return driver_->errnum(); } const char* Connection::error() const { return error_message_.size() ? error_message_.c_str() : driver_->error(); } std::string Connection::ipc_info() const { return driver_->ipc_info(); } bool Connection::kill(unsigned long tid) const { error_message_.clear(); return driver_->kill(tid); } Connection& Connection::operator=(const Connection& rhs) { copy(rhs); return *this; } bool Connection::parse_ipc_method(const char* server, std::string& host, unsigned int& port, std::string& socket_name) { // NOTE: This routine has no connection type knowledge. It can only // recognize a 0 value for the server parameter. All substantial // tests are delegated to our specialized subclasses, which figure // out what kind of connection the server address denotes. We do // the platform-specific tests first as they're the most reliable. if (server == 0) { // Just take all the defaults return true; } else if (WindowsNamedPipeConnection::is_wnp(server)) { // Use Windows named pipes host = server; return true; } else if (UnixDomainSocketConnection::is_socket(server)) { // Use Unix domain sockets socket_name = server; return true; } else { // Failing above, it can only be some kind of TCP/IP address. host = server; return TCPConnection::parse_address(host, port, error_message_); } } bool Connection::ping() { if (connected()) { error_message_.clear(); return driver_->ping(); } else { // Not connected, and we've forgotten everything we need in // order to re-connect, if we once were connected. build_error_message("ping database server"); return false; } } int Connection::protocol_version() const { return driver_->protocol_version(); } Query Connection::query(const char* qstr) { return Query(this, throw_exceptions(), qstr); } Query Connection::query(const std::string& qstr) { return query(qstr.c_str()); } bool Connection::select_db(const std::string& db) { error_message_.clear(); if (connected()) { if (driver_->select_db(db.c_str())) { return true; } else { if (throw_exceptions()) { throw DBSelectionFailed(error(), errnum()); } return false; } } else { build_error_message("select a database"); if (throw_exceptions()) { throw DBSelectionFailed(error_message_.c_str()); } return false; } } std::string Connection::server_status() const { return driver_->server_status(); } std::string Connection::server_version() const { return driver_->server_version(); } bool Connection::set_option(Option* o) { const std::type_info& oti = typeid(*o); if (driver_->set_option(o)) { error_message_.clear(); return true; } else { error_message_ = driver_->error(); if (throw_exceptions()) { throw BadOption(error_message_, oti); } return false; } } bool Connection::shutdown() { error_message_.clear(); if (connected()) { if (driver_->shutdown()) { return true; } else { if (throw_exceptions()) { throw ConnectionFailed(error(), errnum()); } return false; } } else { build_error_message("shutdown database server"); if (throw_exceptions()) { throw ConnectionFailed(error_message_.c_str()); } return false; } } bool Connection::thread_aware() { return DBDriver::thread_aware(); } void Connection::thread_end() { DBDriver::thread_end(); } unsigned long Connection::thread_id() { return driver_->thread_id(); } bool Connection::thread_start() { return DBDriver::thread_start(); } } // end namespace mysqlpp |
Changes to lib/connection.h.
1 2 3 4 | /// \file connection.h /// \brief Declares the Connection class. /// /// Every program using MySQL++ must create a Connection object, which | | | | | | | < < | < < | < > > > | > | < < < < < < < < < < < < < | | < < < < < < < | < < < > < < < < < < < < < < < < < < < < < < > | > | | | < > | < < > | | | < < < < | | | | | | | | | | > > > > > > | < | < < > > > > > > > > | | | > | < > > > | | > > > > | < < < | < < < < < < < < | < < < | | | < < < < < < < < < < < < | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < | < | | > > > > > > > > > > > > > > | | | | > | | < | > > | | | | < < | | | | | | | | > > > > > | | < | < | | > > | < | < < > > > | | < > | > | > | > | | < > > | > > | > > > | | > > > > | < | < < < < < | > | > > > > | > > > > > | | < > | < | > | > > > | < < < | < > > > > > > | > > > < < < < > > | > | < > | | | > > | > > > | < < < < > > | | < < | < > < > > > > | < > > > > > > > > > > > > > > | < < < < | < | | < < | < < < < < < | < | < < | < < | < < < | < < < < | < < < < < < < < < < < | < < < < < | < < < < < < < | < < < < < < | < | < < < < < | < | < < < < < < < < | < | | < < < < < < < | | 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 connection.h /// \brief Declares the Connection class. /// /// Every program using MySQL++ must create a Connection object, which /// manages information about the connection to the database server, 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-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.txt 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_CONNECTION_H) #define MYSQLPP_CONNECTION_H #include "common.h" #include "noexceptions.h" #include "options.h" #include <string> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT Query; class DBDriver; #endif /// \brief Manages the connection to the database server. /// /// This class is a thick wrapper around DBDriver, adding high-level /// error handling, utility functions, and abstraction away from /// underlying C API details. class MYSQLPP_EXPORT Connection : public OptionalExceptions { private: /// \brief Pointer to bool data member, for use by safe bool /// conversion operator. /// /// \see http://www.artima.com/cppsource/safebool.html typedef bool Connection::*private_bool_type; public: /// \brief Create object without connecting to the database 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 database server. /// /// \param db name of database to select upon connection /// \param server specifies the IPC method and parameters for /// contacting the server; see below for details /// \param user user name to log in under, or 0 to use the user /// name this program is running under /// \param password password to use when logging in /// \param port TCP port number database server is listening on, or /// 0 to use default value; note that you may also give this as /// part of the \c server parameter /// /// The server parameter can be any of several different forms: /// /// - \b 0: Let the database driver decide how to connect; usually /// some sort of localhost IPC method. /// - \b ".": On Windows, this means named pipes, if the server /// supports it /// - \b "/some/domain/socket/path": If the passed string doesn't /// match one of the previous alternatives and we're on a system /// that supports Unix domain sockets, MySQL++ will test it to see /// if it names one, and use it if we have permission. /// - \b "host.name.or.ip:port": If the previous test fails, or if /// the system doesn't support Unix domain sockets at all, it /// assumes the string is some kind of network address, optionally /// followed by a colon and port. The name can be in dotted quad /// form, a host name, or a domain name. The port can either be a /// TCP/IP port number or a symbolic service name. If a port or /// service name is given here and a nonzero value is passed for /// the \c port parameter, the latter takes precedence. Connection(const char* db, const char* server = 0, const char* user = 0, const char* password = 0, unsigned int port = 0); /// \brief Establish a new connection using the same parameters as /// an existing connection. /// /// \param other existing Connection object Connection(const Connection& other); /// \brief Destroy object virtual ~Connection(); /// \brief Get version of library underpinning the current database /// driver. std::string client_version() const; /// \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. virtual bool connect(const char* db = 0, const char* server = 0, const char* user = 0, const char* password = 0, unsigned int port = 0); /// \brief Returns true if connection was established successfully /// /// \return true if connection was established successfully bool connected() const; /// \brief Returns the number of rows in a table /// /// \param table name of table whose rows you want counted /// /// This is syntactic sugar for a \c SELECT \c COUNT(*) /// \c FROM \c table SQL query. ulonglong count_rows(const std::string& table); /// \brief Ask the database server to 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 the connection to the database server void disconnect(); /// \brief Returns a reference to the current database driver /// /// \internal This exists mostly for the benefit of Query, Result /// and ResUse. If there is something you want to use in the /// DBDriver interface, look for something similar in one of these /// classes instead. If you still can't find it, send a message to /// the mailing list asking about it. Unless you're doing something /// very low-level, there should never be a reason to use the /// driver directly. DBDriver* driver() { return driver_; } /// \brief Asks the database server to drop (destroy) a database /// /// \param db name of database to destroy /// /// \return true if database was dropped successfully bool drop_db(const std::string& db); /// \brief Return last error number associated with this /// connection int errnum(); /// \brief Return error message for last error associated with /// this connection. /// /// Returns either a MySQL++-specific error message if one exists, /// or one from the current database driver otherwise. const char* error() const; /// \brief Get information about the IPC connection to the /// database server /// /// String contains info about type of connection (e.g. TCP/IP, /// named pipe, Unix socket...) and the server hostname. std::string ipc_info() const; /// \brief Kill a database server thread /// /// \param tid ID of thread to kill /// /// \see thread_id() bool kill(unsigned long tid) const; /// \brief Test whether any error has occurred within the object. /// /// Allows the object to be used in bool context, like this: /// /// \code /// Connection conn; /// .... use conn /// if (conn) { /// ... nothing bad has happened since last successful use /// } /// else { /// ... some error has occurred /// } /// \endcode /// /// Prior to MySQL++ v3, the object was always falsy when we /// weren't connected. Now a true return simply indicates a lack of /// errors. If you've been using this to test for whether the /// connection is still up, you need to call connected() instead. operator private_bool_type() const { return copacetic_ ? &Connection::copacetic_ : 0; } /// \brief Copy an existing Connection object's state into this /// object. Connection& operator=(const Connection& rhs); /// \brief "Pings" the database server /// /// \retval true if server is responding /// \retval false 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. bool ping(); /// \brief Returns version number of the protocol the database /// driver uses to communicate with the server. int protocol_version() const; /// \brief Return a new query object. /// /// The returned query object is tied to this connection object, /// so when you call a method like /// \link Query::execute() execute() \endlink /// on that object, the query is sent to the server this object /// is connected to. /// /// \param qstr an optional query string for populating the /// new Query object Query query(const char* qstr = 0); /// \brief Return a new query object /// /// \param qstr initial query string Query query(const std::string& qstr); /// \brief Change to a different database managed by the /// database server we are connected to. /// /// \param db database to switch to /// /// \retval true if we changed databases successfully bool select_db(const std::string& db); /// \brief Get the database server's version string std::string server_version() const; /// \brief Sets a connection option /// /// \param o pointer to any derivative of Option allocated on /// the heap /// /// Objects passed to this method and successfully set will be /// released when this Connection object is destroyed. If an error /// occurs while setting the option the object will be deleted /// immediately. /// /// Because there are so many Option subclasses, the actual effect /// of this function has a wide range. This mechanism abstracts /// away many things that are unrelated down at the database driver /// level, hiding them behind a coherent, type-safe interface. /// /// The rules about which options can be set, when, are up to the /// underlying database driver. Some must be set before the /// connection is established because they can only be used during /// that connection setup process. Others can be set at any time /// after the connection comes up. If you get it wrong, you'll get /// a BadOption exception. /// /// \retval true if option was successfully set bool set_option(Option* o); /// \brief Ask database server to shut down. bool shutdown(); /// \brief Returns information about database server's status std::string server_status() const; /// \brief Returns true if both MySQL++ and database driver we're /// using were compiled with thread awareness. static bool thread_aware(); /// \brief Tells the underlying database driver that this thread /// is done using the library. static void thread_end(); /// \brief Returns the database server's thread ID for this connection /// /// This has nothing to do with threading on the client side. The /// only thing you can do with this value is pass it to kill(). unsigned long thread_id(); /// \brief Tells the underlying database driver that the current /// thread is now using its services. /// /// It's not necessary to call this from the thread that creates /// the connection as it's done automatically. This method exists /// for times when multiple threads may use this object; it allows /// the underlying database driver to set up any per-thread data /// structures it needs. /// /// The MySQL++ user manual's <a href="../userman/threads.html">chapter /// on threads</a> details two major strategies for dealing with /// connections in the face of threads. The Connection-per-thread /// option frees you from ever having to call this method. The /// other documented strategy is to use ConnectionPool, which opens /// the possibility for one thread to create a connection that /// another uses, so you do need to call this method in that case, /// or with any other similar strategy. /// /// \retval True if there was no problem static bool thread_start(); protected: /// \brief Build an error message in the standard form used whenever /// one of the methods can't succeed because we're not connected to /// the database server. void build_error_message(const char* core); /// \brief Establish a new connection as a copy of an existing one /// /// \param other the connection to copy void copy(const Connection& other); /// \brief Extract elements from the server parameter in formats /// suitable for passing to DBDriver::connect(). bool parse_ipc_method(const char* server, std::string& host, unsigned int& port, std::string& socket_name); //// Subclass data mutable std::string error_message_; ///< MySQL++ specific error, if any private: DBDriver* driver_; bool copacetic_; }; } // end namespace mysqlpp // Not strictly required, but bring in our specialization subclasses #include "tcp_connection.h" #include "uds_connection.h" #include "wnp_connection.h" #endif // !defined(MYSQLPP_CONNECTION_H) |
Deleted lib/const_string.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/convert.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added lib/cpool.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 | /*********************************************************************** cpool.cpp - Implements the ConnectionPool class. Copyright (c) 2007-2009 by Educational Technology Resources, Inc. and (c) 2007 by Jonathan Wakely. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "cpool.h" #include "connection.h" #include <algorithm> #include <functional> namespace mysqlpp { /// \brief Functor to test whether a given ConnectionInfo object is /// "too old". /// /// \internal This is a template only because ConnectionInfo is private. /// Making it a template means the private type is only used at the point /// of instantiation, where it is accessible. template <typename ConnInfoT> class TooOld : std::unary_function<ConnInfoT, bool> { public: #if !defined(DOXYGEN_IGNORE) TooOld(unsigned int tmax) : min_age_(time(0) - tmax) { } bool operator()(const ConnInfoT& conn_info) const { return !conn_info.in_use && conn_info.last_used <= min_age_; } #endif private: time_t min_age_; }; //// clear ///////////////////////////////////////////////////////////// // Destroy connections in the pool, either all of them (completely // draining the pool) or just those not currently in use. The public // method shrink() is an alias for clear(false). void ConnectionPool::clear(bool all) { ScopedLock lock(mutex_); // ensure we're not interfered with PoolIt it = pool_.begin(); while (it != pool_.end()) { if (all || !it->in_use) { remove(it++); } else { ++it; } } } //// exchange ////////////////////////////////////////////////////////// // Passed connection is defective, so remove it from the pool and return // a new one. Connection* ConnectionPool::exchange(const Connection* pc) { // Don't grab the mutex first. remove() and grab() both do. // Inefficient, but we'd have to hoist their contents up into this // method or extract a mutex-free version of each mechanism for // each, both of which are also inefficient. remove(pc); return grab(); } //// find_mru ////////////////////////////////////////////////////////// // Find most recently used available connection. Uses operator< for // ConnectionInfo to order pool with MRU connection last. Returns 0 if // there are no connections not in use. Connection* ConnectionPool::find_mru() { PoolIt mru = std::max_element(pool_.begin(), pool_.end()); if (mru != pool_.end() && !mru->in_use) { mru->in_use = true; return mru->conn; } else { return 0; } } //// grab ////////////////////////////////////////////////////////////// Connection* ConnectionPool::grab() { ScopedLock lock(mutex_); // ensure we're not interfered with remove_old_connections(); if (Connection* mru = find_mru()) { return mru; } else { // No free connections, so create and return a new one. pool_.push_back(ConnectionInfo(create())); return pool_.back().conn; } } //// release /////////////////////////////////////////////////////////// void ConnectionPool::release(const Connection* pc) { ScopedLock lock(mutex_); // ensure we're not interfered with for (PoolIt it = pool_.begin(); it != pool_.end(); ++it) { if (it->conn == pc) { it->in_use = false; it->last_used = time(0); break; } } } //// remove //////////////////////////////////////////////////////////// // 2 versions: // // First takes a Connection pointer, finds it in the pool, and calls // the second. It's public, because Connection pointers are all // outsiders see of the pool. // // Second takes an iterator into the pool, destroys the referenced // connection and removes it from the pool. This is only a utility // function for use by other class internals. void ConnectionPool::remove(const Connection* pc) { ScopedLock lock(mutex_); // ensure we're not interfered with for (PoolIt it = pool_.begin(); it != pool_.end(); ++it) { if (it->conn == pc) { remove(it); return; } } } void ConnectionPool::remove(const PoolIt& it) { // Don't grab the mutex. Only called from other functions that do // grab it. destroy(it->conn); pool_.erase(it); } //// remove_old_connections //////////////////////////////////////////// // Remove connections that were last used too long ago. void ConnectionPool::remove_old_connections() { TooOld<ConnectionInfo> too_old(max_idle_time()); PoolIt it = pool_.begin(); while ((it = std::find_if(it, pool_.end(), too_old)) != pool_.end()) { remove(it++); } } //// safe_grab ///////////////////////////////////////////////////////// Connection* ConnectionPool::safe_grab() { Connection* pc; while (!(pc = grab())->ping()) { remove(pc); pc = 0; } return pc; } } // end namespace mysqlpp |
Added lib/cpool.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 cpool.h /// \brief Declares the ConnectionPool class. /*********************************************************************** Copyright (c) 2007-2008 by Educational Technology Resources, Inc. and (c) 2007 by Jonathan Wakely. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_CPOOL_H) #define MYSQLPP_CPOOL_H #include "beemutex.h" #include <list> #include <assert.h> #include <time.h> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT Connection; #endif /// \brief Manages a pool of connections for programs that need more /// than one Connection object at a time, but can't predict how many /// they need in advance. /// /// This class is useful in programs that need to make multiple /// simultaneous queries on the database; this requires multiple /// Connection objects due to a hard limitation of the underlying /// C API. Connection pools are most useful in multithreaded programs, /// but it can be helpful to have one in a single-threaded program as /// well. Sometimes it's necessary to get more data from the server /// while in the middle of processing data from an earlier query; this /// requires multiple connections. Whether you use a pool or manage /// connections yourself is up to you, but realize that this class /// takes care of a lot of subtle details for you that aren't obvious. /// /// The pool's policy for connection reuse is to always return the /// \em most recently used connection that's not being used right now. /// This ensures that excess connections don't hang around any longer /// than they must. If the pool were to return the \em least recently /// used connection, it would be likely to result in a large pool of /// sparsely used connections because we'd keep resetting the last-used /// time of whichever connection is least recently used at that moment. class MYSQLPP_EXPORT ConnectionPool { public: /// \brief Create empty pool ConnectionPool() { } /// \brief Destroy object /// /// If the pool raises an assertion on destruction, it means our /// subclass isn't calling clear() in its dtor as it should. virtual ~ConnectionPool() { assert(empty()); } /// \brief Returns true if pool is empty bool empty() const { return pool_.empty(); } /// \brief Return a defective connection to the pool and get a new /// one back. /// /// Call this on receiving a BadQuery exception, with errnum() /// equal to CR_SERVER_GONE_ERROR. It means the server was /// restarted or otherwise dropped your connection to it, so the /// Connection object is no longer usable. You can avoid the /// need to use this by setting the ReconnectOption in your grab() /// override, but perhaps there are other reasons to need to /// exchange a bad connection for a good one. /// /// This function wraps grab(), not safe_grab(), even though that /// could return another dead connection. The assumption is that if /// your code is smart enough to detect one bad connection, it should /// be smart enough to detect a whole string of them. Worst case, /// the whole pool is bad -- remote server went away -- and we have /// to empty the pool and start re-filling it. /// /// \param pc pointer to a Connection object to be returned to the /// pool and marked as unused. /// /// \retval a pointer to a different Connection object; not /// guaranteed to still be connected! virtual Connection* exchange(const Connection* pc); /// \brief Grab a free connection from the pool. /// /// This method creates a new connection if an unused one doesn't /// exist, and destroys any that have remained unused for too long. /// If there is more than one free connection, we return the most /// recently used one; this allows older connections to die off over /// time when the caller's need for connections decreases. /// /// Do not delete the returned pointer. This object manages the /// lifetime of connection objects it creates. /// /// \retval a pointer to the connection virtual Connection* grab(); /// \brief Return a connection to the pool /// /// Marks the connection as no longer in use. /// /// The pool updates the last-used time of a connection only on /// release, on the assumption that it was used just prior. There's /// nothing forcing you to do it this way: your code is free to /// delay releasing idle connections as long as it likes. You /// want to avoid this because it will make the pool perform poorly; /// if it doesn't know approximately how long a connection has /// really been idle, it can't make good judgements about when to /// remove it from the pool. /// /// \param pc pointer to a Connection object to be returned to the /// pool and marked as unused. virtual void release(const Connection* pc); /// \brief Removes the given connection from the pool /// /// If you mean to simply return a connection to the pool after /// you're finished using it, call release() instead. This method /// is primarily for error handling: you somehow have figured out /// that the connection is defective, so want it destroyed and /// removed from the pool. If you also want a different connection /// to retry your operation on, call exchange() instead. /// /// \param pc pointer to a Connection object to be removed from /// the pool and destroyed void remove(const Connection* pc); /// \brief Grab a free connection from the pool, testing that it's /// connected before returning it. /// /// This is just a wrapper around grab(), Connection::ping() and /// release(), and is thus less efficient than grab(). Use it only /// when it's possible for MySQL server connections to go away /// unexpectedly, such as when the DB server can be restarted out /// from under your application. /// /// \retval a pointer to the connection virtual Connection* safe_grab(); /// \brief Remove all unused connections from the pool void shrink() { clear(false); } protected: /// \brief Drains the pool, freeing all allocated memory. /// /// A derived class must call this in its dtor to avoid leaking all /// Connection objects still in existence. We can't do it up at /// this level because this class's dtor can't call our subclass's /// destroy() method. /// /// \param all if true, remove all connections, even those in use void clear(bool all = true); /// \brief Create a new connection /// /// Subclasses must override this. /// /// Essentially, this method lets your code tell ConnectionPool /// what server to connect to, what login parameters to use, what /// connection options to enable, etc. ConnectionPool can't know /// any of this without your help. /// /// \retval A connected Connection object virtual Connection* create() = 0; /// \brief Destroy a connection /// /// Subclasses must override this. /// /// This is for destroying the objects returned by create(). /// Because we can't know what the derived class did to create the /// connection we can't reliably know how to destroy it. virtual void destroy(Connection*) = 0; /// \brief Returns the maximum number of seconds a connection is /// able to remain idle before it is dropped. /// /// Subclasses must override this as it encodes a policy issue, /// something that MySQL++ can't declare by fiat. /// /// \retval number of seconds before an idle connection is destroyed /// due to lack of use virtual unsigned int max_idle_time() = 0; /// \brief Returns the current size of the internal connection pool. size_t size() const { return pool_.size(); } private: //// Internal types struct ConnectionInfo { Connection* conn; time_t last_used; bool in_use; ConnectionInfo(Connection* c) : conn(c), last_used(time(0)), in_use(true) { } // Strict weak ordering for ConnectionInfo objects. // // This ordering defines all in-use connections to be "less // than" those not in use. Within each group, connections // less recently touched are less than those more recent. bool operator<(const ConnectionInfo& rhs) const { const ConnectionInfo& lhs = *this; return lhs.in_use == rhs.in_use ? lhs.last_used < rhs.last_used : lhs.in_use; } }; typedef std::list<ConnectionInfo> PoolT; typedef PoolT::iterator PoolIt; //// Internal support functions Connection* find_mru(); void remove(const PoolIt& it); void remove_old_connections(); //// Internal data PoolT pool_; BeecryptMutex mutex_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_CPOOL_H) |
Deleted lib/custom-macros.h.
more than 10,000 changes
Deleted lib/custom.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/custom.pl.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/datetime.cpp.
1 2 3 4 | /*********************************************************************** datetime.cpp - Implements date and time classes compatible with MySQL's various date and time column types. | | | | | | > > > > > > > > > > > > > > > > > > > > > > | | | | | | > > > > | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > | | | | > | | | | | | | | > > > | | | | > | | | | > | > > > > | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /*********************************************************************** 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-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "stream2string.h" #include <iomanip> #include <stdlib.h> #include <time.h> using namespace std; namespace mysqlpp { static void safe_localtime(struct tm* ptm, const time_t t) { #if defined(MYSQLPP_HAVE_LOCALTIME_S) // common.h detected localtime_s() from native RTL of VC++ 2005 and up localtime_s(ptm, &t); #elif defined(HAVE_LOCALTIME_R) // autoconf detected POSIX's localtime_r() on this system localtime_r(&t, ptm); #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, such as TLS. memcpy(ptm, localtime(&t), sizeof(tm)); #endif } 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) << static_cast<int>(d.month()) << '-' << setw(2) << static_cast<int>(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) << static_cast<int>(t.hour()) << ':' << setw(2) << static_cast<int>(t.minute()) << ':' << setw(2) << static_cast<int>(t.second()); os.flags(flags); os.fill(fill); return os; } std::ostream& operator <<(std::ostream& os, const DateTime& dt) { if (dt.is_now()) { return os << "NOW()"; } else { operator <<(os, Date(dt)); os << ' '; return operator <<(os, Time(dt)); } } Date::Date(time_t t) { struct tm tm; safe_localtime(&tm, t); year_ = tm.tm_year + 1900; month_ = tm.tm_mon + 1; day_ = tm.tm_mday; } DateTime::DateTime(time_t t) { struct tm tm; safe_localtime(&tm, t); 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; now_ = false; } Time::Time(time_t t) { struct tm tm; safe_localtime(&tm, t); hour_ = tm.tm_hour; minute_ = tm.tm_min; second_ = tm.tm_sec; } const char* Date::convert(const char* str) { char num[5]; num[0] = *str++; num[1] = *str++; num[2] = *str++; num[3] = *str++; num[4] = 0; year_ = static_cast<unsigned short>(strtol(num, 0, 10)); if (*str == '-') str++; num[0] = *str++; num[1] = *str++; num[2] = 0; month_ = static_cast<unsigned char>(strtol(num, 0, 10)); if (*str == '-') str++; num[0] = *str++; num[1] = *str++; num[2] = 0; day_ = static_cast<unsigned char>(strtol(num, 0, 10)); return str; } const char* Time::convert(const char* str) { char num[5]; num[0] = *str++; num[1] = *str++; num[2] = 0; hour_ = static_cast<unsigned char>(strtol(num,0,10)); if (*str == ':') str++; num[0] = *str++; num[1] = *str++; num[2] = 0; minute_ = static_cast<unsigned char>(strtol(num,0,10)); if (*str == ':') str++; num[0] = *str++; num[1] = *str++; num[2] = 0; second_ = static_cast<unsigned char>(strtol(num,0,10)); return str; } const char* DateTime::convert(const char* 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(); now_ = false; return str; } 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_; } 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_; } int DateTime::compare(const DateTime& other) const { if (now_ && other.now_) { return 0; } else { Date d(*this), od(other); Time t(*this), ot(other); if (int x = d.compare(od)) { return x; } else { return t.compare(ot); } } } Date::operator std::string() const { return stream2string(*this); } DateTime::operator std::string() const { return stream2string(*this); } Time::operator std::string() const { return stream2string(*this); } Date::operator time_t() const { struct tm tm; safe_localtime(&tm, time(0)); tm.tm_mday = day_; tm.tm_mon = month_ - 1; tm.tm_year = year_ - 1900; tm.tm_isdst = -1; return mktime(&tm); } DateTime::operator time_t() const { if (now_) { // Many factors combine to make it almost impossible for this // case to return the same value as you'd get if you used this // in a query. But, you gotta better idea than to return the // current time for an object initialized with the value "now"? return time(0); } else { struct tm tm; tm.tm_sec = second_; tm.tm_min = minute_; tm.tm_hour = hour_; tm.tm_mday = day_; tm.tm_mon = month_ - 1; tm.tm_year = year_ - 1900; tm.tm_isdst = -1; return mktime(&tm); } } Time::operator time_t() const { struct tm tm; safe_localtime(&tm, time(0)); tm.tm_sec = second_; tm.tm_min = minute_; tm.tm_hour = hour_; tm.tm_isdst = -1; return mktime(&tm); } } // end namespace mysqlpp |
Changes to lib/datetime.h.
1 | /// \file 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 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 | /// \file datetime.h /// \brief Declares classes to add SQL-compatible date and time /// types to C++'s type system. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_DATETIME_H) #define MYSQLPP_DATETIME_H #include "common.h" #include "comparable.h" #include <string> #include <iostream> namespace mysqlpp { /// \brief C++ form of SQL's DATETIME type. /// /// This object exists primarily for conversion purposes. You can /// initialize it in several different ways, and then convert the object /// to SQL string form, extract the individual y/m/d h:m:s values, /// convert it to C's time_t, etc. class MYSQLPP_EXPORT DateTime : public Comparable<DateTime> { public: /// \brief Default constructor DateTime() : Comparable<DateTime>(), year_(0), month_(0), day_(0), hour_(0), minute_(0), second_(0), now_(true) { } /// \brief Initialize object from discrete y/m/d h:m:s values. /// /// \param y year, 1000-9999 /// \param mon month, 1-12 /// \param d day of month, 1-31 /// \param h hour, 0-23 /// \param min minute, 0-59 /// \param s second, 0-59 DateTime(unsigned short y, unsigned char mon, unsigned char d, unsigned char h, unsigned char min, unsigned char s) : Comparable<DateTime>(), year_(y), month_(mon), day_(d), hour_(h), minute_(min), second_(s), now_(false) { } /// \brief Initialize object as a copy of another Date DateTime(const DateTime& other) : Comparable<DateTime>(), year_(other.year_), month_(other.month_), day_(other.day_), hour_(other.hour_), minute_(other.minute_), second_(other.second_), now_(other.now_) { } /// \brief Initialize object from a C string containing a SQL /// date-and-time string /// /// String must be in the HH:MM:SS format. It doesn't have to be /// zero-padded. explicit DateTime(const char* str) { convert(str); } /// \brief Initialize object from a C++ string containing a /// SQL date-and-time string /// /// This works with any stringish class that declares a c_str() /// member function: std::string, mysqlpp::String... /// /// \sa DateTime(const char*) template <class Str> explicit DateTime(const Str& str) { convert(str.c_str()); } /// \brief Initialize object from a \c time_t explicit DateTime(time_t t); /// \brief Compare this object to another. /// /// Returns < 0 if this object is before the other, 0 of they are /// equal, and > 0 if this object is after the other. int compare(const DateTime& other) const; /// \brief Parse a SQL date and time string into this object. const char* convert(const char*); /// \brief Get the date/time value's day part, 1-31 unsigned char day() const { return day_; } /// \brief Change the date/time value's day part, 1-31 void day(unsigned char d) { day_ = d; now_ = false; } /// \brief Get the date/time value's hour part, 0-23 unsigned char hour() const { return hour_; } /// \brief Change the date/time value's hour part, 0-23 void hour(unsigned char h) { hour_ = h; now_ = false; } /// \brief Returns true if object will evaluate to SQL "NOW()" on /// conversion to string. bool is_now() const { return now_; } /// \brief Get the date/time value's minute part, 0-59 unsigned char minute() const { return minute_; } /// \brief Change the date/time value's minute part, 0-59 void minute(unsigned char m) { minute_ = m; now_ = false; } /// \brief Get the date/time value's month part, 1-12 unsigned char month() const { return month_; } /// \brief Change the date/time value's month part, 1-12 void month(unsigned char m) { month_ = m; now_ = false; } /// \brief Factory to create an object instance that will convert /// to SQL "NOW()" on insertion into a query /// /// This is just syntactic sugar around the default ctor static DateTime now() { return DateTime(); } /// \brief Convert to std::string operator std::string() const; /// \brief Convert to time_t operator time_t() const; /// \brief Get the date/time value's second part, 0-59 unsigned char second() const { return second_; } /// \brief Change the date/time value's second part, 0-59 void second(unsigned char s) { second_ = s; now_ = false; } /// \brief Return our value in std::string form std::string str() const { return *this; } /// \brief Get the date/time value's year part /// /// There's no trickery here like in some date/time implementations /// where you have to add 1900 or something like that. It simply /// returns the year in natural form, in the range 1000-9999. unsigned short year() const { return year_; } /// \brief Change the date/time value's year part /// /// Pass the year value normally; we don't optimize the value by /// subtracting 1900 like some other date/time implementations. void year(unsigned short y) { year_ = y; now_ = false; } private: unsigned short year_; ///< the year, as a simple integer unsigned char month_; ///< the month, 1-12 unsigned char day_; ///< the day, 1-31 unsigned char hour_; ///< the hour, 0-23 (not 0-255 as in Time!) unsigned char minute_; ///< the minute, 0-59 unsigned char second_; ///< the second, 0-59 bool now_; ///< true if object not initialized with explicit value }; /// \brief Returns a DateTime object that, when inserted into query /// will yield a SQL "NOW()" function call. inline DateTime NOW() { return DateTime(); } /// \brief Inserts a DateTime object into a C++ stream in a /// SQL-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 SQL's DATE type. /// /// Objects of this class can be inserted into streams, and /// initialized from SQL DATE strings. class MYSQLPP_EXPORT Date : public Comparable<Date> { public: /// \brief Default constructor Date() : year_(0), month_(0), day_(0) { } /// \brief Initialize object /// /// \param y year, 1000-9999 /// \param m month, 1-12 /// \param d day of month, 1-31 Date(unsigned short y, unsigned char m, unsigned char d) : Comparable<Date>(), year_(y), month_(m), day_(d) { } /// \brief Initialize object as a copy of another Date Date(const Date& other) : Comparable<Date>(), year_(other.year_), month_(other.month_), day_(other.day_) { } /// \brief Initialize object from date part of date/time object Date(const DateTime& other) : Comparable<Date>(), year_(other.year()), month_(other.month()), day_(other.day()) { } /// \brief Initialize object from a C string containing a date /// /// String must be in the YYYY-MM-DD format. It doesn't have to be /// zero-padded. explicit Date(const char* str) { convert(str); } /// \brief Initialize object from a C++ string containing a date /// /// This works with any stringish class that declares a c_str() /// member function: std::string, mysqlpp::String... /// /// \sa Date(const char*) template <class Str> explicit Date(const Str& str) { convert(str.c_str()); } /// \brief Initialize object from a \c time_t /// /// Naturally, we throw away the "time" part of the \c time_t. If /// you need to keep it, you want to use DateTime instead. explicit Date(time_t t); /// \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. int compare(const Date& other) const; /// \brief Parse a SQL date string into this object. const char* convert(const char*); /// \brief Get the date's day part, 1-31 unsigned char day() const { return day_; } /// \brief Change the date's day part, 1-31 void day(unsigned char d) { day_ = d; } /// \brief Get the date's month part, 1-12 unsigned char month() const { return month_; } /// \brief Change the date's month part, 1-12 void month(unsigned char m) { month_ = m; } /// \brief Convert to std::string operator std::string() const; /// \brief Convert to time_t /// /// The "time" part of the \c time_t is "now" operator time_t() const; /// \brief Return our value in std::string form std::string str() const { return *this; } /// \brief Get the date's year part /// /// There's no trickery here like in some date implementations /// where you have to add 1900 or something like that. unsigned short year() const { return year_; } /// \brief Change the date's year part /// /// Pass the year value normally; we don't optimize the value by /// subtracting 1900 like some other date implementations. void year(unsigned short y) { year_ = y; } private: unsigned short year_; ///< the year, as a simple integer, 1000-9999 unsigned char month_; ///< the month, 1-12 unsigned char day_; ///< the day, 1-31 }; /// \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 SQL's TIME type. /// /// Objects of this class can be inserted into streams, and /// initialized from SQL TIME strings. class MYSQLPP_EXPORT Time : public Comparable<Time> { public: /// \brief Default constructor Time() : hour_(0), minute_(0), second_(0) { } /// \brief Initialize object /// \param h hour, 0-255 (yes, > 1 day is legal in SQL!) /// \param m minute, 0-59 /// \param s second, 0-59 Time(unsigned char h, unsigned char m, unsigned char s) : hour_(h), minute_(m), second_(s) { } /// \brief Initialize object as a copy of another Time Time(const Time& other) : Comparable<Time>(), hour_(other.hour_), minute_(other.minute_), second_(other.second_) { } /// \brief Initialize object from time part of date/time object Time(const DateTime& other) : Comparable<Time>(), hour_(other.hour()), minute_(other.minute()), second_(other.second()) { } /// \brief Initialize object from a C string containing a SQL /// time string /// /// String must be in the HH:MM:SS format. It doesn't have to be /// zero-padded. explicit Time(const char* str) { convert(str); } /// \brief Initialize object from a C++ string containing a /// SQL time string /// /// This works with any stringish class that declares a c_str() /// member function: std::string, mysqlpp::String... /// /// \sa Time(const char*) template <class Str> explicit Time(const Str& str) { convert(str.c_str()); } /// \brief Initialize object from a \c time_t /// /// Naturally, we throw away the "date" part of the \c time_t. If /// you need to keep it, you want to use DateTime instead. explicit Time(time_t t); /// \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. int compare(const Time& other) const; /// \brief Parse a SQL time string into this object. const char* convert(const char*); /// \brief Get the time's hour part, 0-255 unsigned char hour() const { return hour_; } /// \brief Change the time's hour part, 0-255 void hour(unsigned char h) { hour_ = h; } /// \brief Get the time's minute part, 0-59 unsigned char minute() const { return minute_; } /// \brief Change the time's minute part, 0-59 void minute(unsigned char m) { minute_ = m; } /// Convert to std::string operator std::string() const; /// \brief Convert to time_t /// /// The "date" part of the \c time_t is "today" operator time_t() const; /// \brief Get the time's second part, 0-59 unsigned char second() const { return second_; } /// \brief Change the time's second part, 0-59 void second(unsigned char s) { second_ = s; } /// Return our value in std::string form std::string str() const { return *this; } private: unsigned char hour_; ///< the hour, 0-255 (yes, > 1 day is legal SQL!) unsigned char minute_; ///< the minute, 0-59 unsigned char second_; ///< the second, 0-59 }; /// \brief Inserts a Time object into a C++ stream in a SQL-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) |
Added lib/dbdriver.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 | /*********************************************************************** dbdriver.cpp - Implements the DBDriver class. Copyright (c) 2005-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "dbdriver.h" #include "exceptions.h" #include <cstring> #include <memory> #include <sstream> // 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 using namespace std; namespace mysqlpp { DBDriver::DBDriver() : is_connected_(false) { // We won't allow calls to mysql_*() functions that take a MYSQL // object until we get a connection up. Such calls are nonsense. // MySQL++ coped with them before, but this masks bugs. memset(&mysql_, 0, sizeof(mysql_)); } DBDriver::DBDriver(const DBDriver& other) : is_connected_(false) { copy(other); } DBDriver::~DBDriver() { if (connected()) { disconnect(); } OptionList::const_iterator it; for (it = applied_options_.begin(); it != applied_options_.end(); ++it) { delete *it; } } bool DBDriver::connect(const char* host, const char* socket_name, unsigned int port, const char* db, const char* user, const char* password) { return is_connected_ = connect_prepare() && mysql_real_connect(&mysql_, host, user, password, db, port, socket_name, mysql_.client_flag); } bool DBDriver::connect(const MYSQL& other) { return is_connected_ = connect_prepare() && mysql_real_connect(&mysql_, other.host, other.user, other.passwd, other.db, other.port, other.unix_socket, other.client_flag); } bool DBDriver::connect_prepare() { // Drop previous connection, if any, then prepare underlying C API // library to establish a new connection. if (connected()) { disconnect(); } // Set up to call MySQL C API mysql_init(&mysql_); // Apply any pending options error_message_.clear(); OptionListIt it = pending_options_.begin(); while (it != pending_options_.end() && set_option_impl(*it)) { ++it; } if (it == pending_options_.end()) { pending_options_.clear(); return true; } else { return false; } } void DBDriver::copy(const DBDriver& other) { if (connected()) { disconnect(); } if (other.connected()) { connect(other.mysql_); } } void DBDriver::disconnect() { if (is_connected_) { mysql_close(&mysql_); memset(&mysql_, 0, sizeof(mysql_)); is_connected_ = false; error_message_.clear(); } } bool DBDriver::enable_ssl(const char* key, const char* cert, const char* ca, const char* capath, const char* cipher) { error_message_.clear(); #if defined(HAVE_MYSQL_SSL_SET) return mysql_ssl_set(&mysql_, key, cert, ca, capath, cipher) == 0; #else (void)key; (void)cert; (void)ca; (void)capath; (void)cipher; return false; #endif } size_t DBDriver::escape_string(std::string* ps, const char* original, size_t length) { error_message_.clear(); if (ps == 0) { // Can't do any real work! return 0; } else if (original == 0) { // ps must point to the original data as well as to the // receiving string, so get the pointer and the length from it. original = ps->data(); length = ps->length(); } else if (length == 0) { // We got a pointer to a C++ string just for holding the result // and also a C string pointing to the original, so find the // length of the original. length = strlen(original); } char* escaped = new char[length * 2 + 1]; length = escape_string(escaped, original, length); ps->assign(escaped, length); delete[] escaped; return length; } size_t DBDriver::escape_string_no_conn(std::string* ps, const char* original, size_t length) { if (ps == 0) { // Can't do any real work! return 0; } else if (original == 0) { // ps must point to the original data as well as to the // receiving string, so get the pointer and the length from it. original = ps->data(); length = ps->length(); } else if (length == 0) { // We got a pointer to a C++ string just for holding the result // and also a C string pointing to the original, so find the // length of the original. length = strlen(original); } char* escaped = new char[length * 2 + 1]; length = DBDriver::escape_string_no_conn(escaped, original, length); ps->assign(escaped, length); delete[] escaped; return length; } DBDriver& DBDriver::operator=(const DBDriver& rhs) { copy(rhs); return *this; } string DBDriver::query_info() { error_message_.clear(); const char* i = mysql_info(&mysql_); return i ? string(i) : string(); } bool DBDriver::set_option(unsigned int o, bool arg) { // If we get through this loop and n is 1, only one bit is set in // the option value, which is as it should be. int n = o; while (n && ((n & 1) == 0)) { n >>= 1; } if ((n == 1) && (o >= CLIENT_LONG_PASSWORD) && #if MYSQL_VERSION_ID > 40000 // highest flag value varies by version (o <= CLIENT_MULTI_RESULTS) #else (o <= CLIENT_TRANSACTIONS) #endif ) { // Option value seems sane, so go ahead and set/clear the flag if (arg) { mysql_.client_flag |= o; } else { mysql_.client_flag &= ~o; } return true; } else { // Option value is outside the range we understand, or caller // erroneously passed a value with multiple bits set. return false; } } bool DBDriver::set_option(Option* o) { if (connected()) { return set_option_impl(o); } else { error_message_.clear(); pending_options_.push_back(o); return true; // we won't know if it fails until ::connect() } } bool DBDriver::set_option_impl(Option* o) { std::ostringstream os; std::auto_ptr<Option> cleanup(o); switch (o->set(this)) { case Option::err_NONE: applied_options_.push_back(o); cleanup.release(); break; case Option::err_api_limit: os << "Option not supported by database driver v" << client_version(); throw BadOption(os.str(), typeid(*o)); // mandatory throw! case Option::err_api_reject: os << "Database driver failed to set option"; break; case Option::err_connected: os << "Option can only be set before connection is established"; break; case Option::err_disconnected: os << "Option can only be set while the connection is established"; break; } error_message_ = os.str(); return error_message_.empty(); } bool DBDriver::shutdown() { error_message_.clear(); return mysql_shutdown(&mysql_ SHUTDOWN_ARG); } bool DBDriver::thread_aware() { #if defined(MYSQLPP_PLATFORM_WINDOWS) || defined(HAVE_PTHREAD) || defined(HAVE_SYNCH_H) // Okay, good, MySQL++ itself is thread-aware, but only return true // if the underlying C API library is also thread-aware. return mysql_thread_safe(); #else // MySQL++ itself isn't thread-aware, so we don't need to do any // further tests. All pieces must be thread-aware to return true. return false; #endif } } // end namespace mysqlpp |
Added lib/dbdriver.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 | /// \file dbdriver.h /// \brief Declares the DBDriver class. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_DBDRIVER_H) #define MYSQLPP_DBDRIVER_H #include "common.h" #include "options.h" #include <typeinfo> #include <limits.h> namespace mysqlpp { /// \brief Provides a thin abstraction layer over the underlying database /// client library. /// /// This class does as little as possible to adapt between its public /// interface and the interface required by the underlying C API. That /// is, in fact, its only mission. The high-level interfaces indended /// for use by MySQL++ users are in Connection, Query, Result, and /// ResUse, all of which delegate the actual database communication to /// an object of this type, created by Connection. If you really need /// access to the low-level database driver, get it via /// Connection::driver(); don't create DBDriver objects directly. /// /// Currently this is a concrete class for wrapping the MySQL C API. /// In the future, it may be turned into an abstract base class, with /// subclasses for different database server types. class MYSQLPP_EXPORT DBDriver { public: /// \brief Result code returned by next_result() enum nr_code { nr_more_results, ///< success, with more results to come nr_last_result, ///< success, last result received nr_error, ///< problem retrieving next result nr_not_supported ///< this C API doesn't support "next result" }; /// \brief Create object DBDriver(); /// \brief Duplicate an existing driver /// /// \param other existing DBDriver object /// /// This establishes a new database server connection with the same /// parameters as the other driver's. DBDriver(const DBDriver& other); /// \brief Destroy object virtual ~DBDriver(); /// \brief Return the number of rows affected by the last query /// /// Wraps \c mysql_affected_rows() in the MySQL C API. ulonglong affected_rows() { error_message_.clear(); return mysql_affected_rows(&mysql_); } /// \brief Get database client library version /// /// Wraps \c mysql_get_client_info() in the MySQL C API. std::string client_version() const { error_message_.clear(); return mysql_get_client_info(); } /// \brief Establish a new connection using the same parameters as /// an existing connection. /// /// \param mysql existing MySQL C API connection object bool connect(const MYSQL& mysql); /// \brief Connect to database server /// /// 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. virtual bool connect(const char* host, const char* socket_name, unsigned int port, const char* db, const char* user, const char* password); /// \brief Return true if we have an active connection to the /// database server. /// /// This does not actually check whether the connection is viable, /// it just indicates whether there was previously a successful /// connect() call and no disconnect(). Call ping() to actually /// test the connection's viability. bool connected() const { return is_connected_; } /// \brief Establish a new connection as a copy of an existing one /// /// \param other the connection to copy void copy(const DBDriver& other); /// \brief Ask the database server to create a database /// /// \param db name of database to create /// /// \return true if database was created successfully bool create_db(const char* db) const; /// \brief Seeks to a particualr row within the result set /// /// Wraps mysql_data_seek() in MySQL C API. void data_seek(MYSQL_RES* res, ulonglong offset) const { error_message_.clear(); mysql_data_seek(res, offset); } /// \brief Drop the connection to the database server /// /// This method should only be used by MySQL++ library internals. /// Unless you use the default constructor, this object should /// always be connected. void disconnect(); /// \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) const; /// \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 /// /// \return False if call fails or the C API library wasn't compiled /// with SSL support enabled. /// /// Must be called before connection is established. /// /// Wraps \c mysql_ssl_set() in MySQL C API. bool enable_ssl(const char* key = 0, const char* cert = 0, const char* ca = 0, const char* capath = 0, const char* cipher = 0); /// \brief Return error message for last MySQL error associated with /// this connection. /// /// Can return a MySQL++ DBDriver-specific error message if there /// is one. If not, it simply wraps \c mysql_error() in the MySQL C API. const char* error() { return error_message_.length() ? error_message_.c_str() : mysql_error(&mysql_); } /// \brief Return last MySQL error number associated with this /// connection /// /// Wraps \c mysql_errno() in the MySQL C API. int errnum() { return mysql_errno(&mysql_); } /// \brief Return a SQL-escaped version of the given character /// buffer /// /// \param to character buffer to hold escaped version; must /// point to at least (length * 2 + 1) bytes /// \param from pointer to the character buffer to escape /// \param length number of characters to escape /// /// \retval number of characters placed in escaped /// /// Wraps \c mysql_real_escape_string() in the MySQL C API. /// /// Proper SQL escaping takes the database's current character set /// into account, however if a database connection isn't available /// DBDriver also provides a static version of this same method. /// /// \sa escape_string_no_conn(char*, const char*, size_t) size_t escape_string(char* to, const char* from, size_t length) { error_message_.clear(); return mysql_real_escape_string(&mysql_, to, from, static_cast<unsigned long>(length)); } /// \brief Return a SQL-escaped version of a character buffer /// /// \param ps pointer to C++ string to hold escaped version; if /// original is 0, also holds the original data to be escaped /// \param original if given, pointer to the character buffer to /// escape instead of contents of *ps /// \param length if both this and original are given, number of /// characters to escape instead of ps->length() /// /// \retval number of characters placed in *ps /// /// This method has three basic operation modes: /// /// - Pass just a pointer to a C++ string containing the original /// data to escape, plus act as receptacle for escaped version /// - Pass a pointer to a C++ string to receive escaped string plus /// a pointer to a C string to be escaped /// - Pass nonzero for all parameters, taking original to be a /// pointer to an array of char with given length; does not treat /// null characters as special /// /// There's a degenerate fourth mode, where ps is zero: simply /// returns 0, because there is nowhere to store the result. /// /// Note that if original is 0, we always ignore the length /// parameter even if it is nonzero. Length always comes from /// ps->length() in this case. /// /// ps is a pointer because if it were a reference, the other /// overload would be impossible to call: the compiler would /// complain that the two overloads are ambiguous because /// std::string has a char* conversion ctor. A nice bonus is that /// pointer syntax makes it clearer that the first parameter is an /// "out" parameter. /// /// \see comments for escape_string(char*, const char*, size_t) /// for further details. /// /// \sa escape_string_no_conn(std::string*, const char*, size_t) size_t escape_string(std::string* ps, const char* original, size_t length); /// \brief SQL-escapes the given string without reference to the /// character set of a database server. /// /// Wraps \c mysql_escape_string() in the MySQL C API. /// /// \sa escape_string(char*, const char*, size_t) static size_t escape_string_no_conn(char* to, const char* from, size_t length) { return mysql_escape_string(to, from, static_cast<unsigned long>(length)); } /// \brief SQL-escapes the given string without reference to the /// character set of a database server. /// /// \sa escape_string(std::string*, const char*, size_t), /// escape_string_no_conn(char*, const char*, size_t) static size_t escape_string_no_conn(std::string* ps, const char* original = 0, size_t length = 0); /// \brief Executes the given query string /// /// Wraps \c mysql_real_query() in the MySQL C API. bool execute(const char* qstr, size_t length) { error_message_.clear(); return !mysql_real_query(&mysql_, qstr, static_cast<unsigned long>(length)); } /// \brief Returns the next raw C API row structure from the given /// result set. /// /// This is for "use" query result sets only. "store" queries have /// all the rows already. /// /// Wraps \c mysql_fetch_row() in MySQL C API. MYSQL_ROW fetch_row(MYSQL_RES* res) const { error_message_.clear(); return mysql_fetch_row(res); } /// \brief Returns the lengths of the fields in the current row /// from a "use" query. /// /// Wraps \c mysql_fetch_lengths() in MySQL C API. const unsigned long* fetch_lengths(MYSQL_RES* res) const { error_message_.clear(); return mysql_fetch_lengths(res); } /// \brief Returns information about a particular field in a result /// set /// /// \param res result set to fetch field information for /// \param i field number to fetch information for, if given /// /// If i parameter is given, this call is like a combination of /// field_seek() followed by fetch_field() without the i parameter, /// which otherwise just iterates through the set of fields in the /// given result set. /// /// Wraps \c mysql_fetch_field() and mysql_fetch_field_direct() in /// MySQL C API. (Which one it uses depends on i parameter.) MYSQL_FIELD* fetch_field(MYSQL_RES* res, size_t i = UINT_MAX) const { error_message_.clear(); return i == UINT_MAX ? mysql_fetch_field(res) : mysql_fetch_field_direct(res, static_cast<unsigned int>(i)); } /// \brief Jumps to the given field within the result set /// /// Wraps \c mysql_field_seek() in MySQL C API. void field_seek(MYSQL_RES* res, size_t field) const { error_message_.clear(); mysql_field_seek(res, MYSQL_FIELD_OFFSET(field)); } /// \brief Releases memory used by a result set /// /// Wraps \c mysql_free_result() in MySQL C API. void free_result(MYSQL_RES* res) const { error_message_.clear(); mysql_free_result(res); } /// \brief Return the connection options object st_mysql_options get_options() const { return mysql_.options; } /// \brief Get information about the IPC connection to the /// database server /// /// String contains info about type of connection (e.g. TCP/IP, /// named pipe, Unix socket...) and the server hostname. /// /// Wraps \c mysql_get_host_info() in the MySQL C API. std::string ipc_info() { error_message_.clear(); return mysql_get_host_info(&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. This /// applies to stored procedure calls because this function returns /// the ID generated by the last query, which was a CALL statement, /// and CALL doesn't generate IDs. You need to use LAST_INSERT_ID() /// to get the ID in this case. ulonglong insert_id() { error_message_.clear(); return mysql_insert_id(&mysql_); } /// \brief Kill a MySQL server thread /// /// \param tid ID of thread to kill /// /// Wraps \c mysql_kill() in the MySQL C API. /// /// \see thread_id() bool kill(unsigned long tid) { error_message_.clear(); return !mysql_kill(&mysql_, tid); } /// \brief Returns true if there are unconsumed results from the /// most recent query. /// /// Wraps \c mysql_more_results() in the MySQL C API. bool more_results() { error_message_.clear(); #if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 + return mysql_more_results(&mysql_); #else return false; #endif } /// \brief Moves to the next result set from a multi-query /// /// \return A code indicating whether we successfully found another /// result, there were no more results (but still success) or /// encountered an error trying to find the next result set. /// /// Wraps \c mysql_next_result() in the MySQL C API, with /// translation of its return value from magic integers to nr_code /// enum values. nr_code next_result() { error_message_.clear(); #if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 + switch (mysql_next_result(&mysql_)) { case 0: return nr_more_results; case -1: return nr_last_result; default: return nr_error; } #else return nr_not_supported; #endif } /// \brief Returns the number of fields in the given result set /// /// Wraps \c mysql_num_fields() in MySQL C API. int num_fields(MYSQL_RES* res) const { error_message_.clear(); return mysql_num_fields(res); } /// \brief Returns the number of rows in the given result set /// /// Wraps \c mysql_num_rows() in MySQL C API. ulonglong num_rows(MYSQL_RES* res) const { error_message_.clear(); return mysql_num_rows(res); } /// \brief "Pings" the MySQL database /// /// This function will try to reconnect to the server if the /// connection has been dropped. Wraps \c mysql_ping() in the MySQL C API. /// /// \retval true if server is responding, regardless of whether we had /// to reconnect or not /// \retval false 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. bool ping() { error_message_.clear(); return !mysql_ping(&mysql_); } /// \brief Returns version number of MySQL protocol this connection /// is using /// /// Wraps \c mysql_get_proto_info() in the MySQL C API. int protocol_version() { error_message_.clear(); return mysql_get_proto_info(&mysql_); } /// \brief Returns information about the last executed query /// /// Wraps \c mysql_info() in the MySQL C API std::string query_info(); /// \brief Asks the database server to refresh certain internal data /// structures. /// /// Wraps \c mysql_refresh() in the MySQL C API. There is no /// corresponding interface for this in higher level MySQL++ classes /// because it was undocumented until recently, and it's a pretty /// low-level thing. It's designed for things like MySQL /// Administrator. bool refresh(unsigned options) { error_message_.clear(); return !mysql_refresh(&mysql_, options); } /// \brief Returns true if the most recent result set was empty /// /// Wraps \c mysql_field_count() in the MySQL C API, returning true /// if it returns 0. bool result_empty() { error_message_.clear(); return mysql_field_count(&mysql_) == 0; } /// \brief Asks the database server to switch to a different database bool select_db(const char* db) { error_message_.clear(); return !mysql_select_db(&mysql_, db); } /// \brief Get the database server's version number /// /// Wraps \c mysql_get_server_info() in the MySQL C API. std::string server_version() { error_message_.clear(); return mysql_get_server_info(&mysql_); } /// \brief Sets a connection option /// /// This is the database-independent high-level option setting /// interface that Connection::set_option() calls. There are /// several private overloads that actually implement the option /// setting. /// /// \see Connection::set_option(Option*) for commentary bool set_option(Option* o); /// \brief Set MySQL C API connection option /// /// \internal Wraps \c mysql_options() in C API. bool set_option(mysql_option moption, const void* arg = 0) { error_message_.clear(); return !mysql_options(&mysql_, moption, static_cast<const char*>(arg)); } #if MYSQL_VERSION_ID >= 40101 /// \brief Set MySQL C API connection option /// /// \internal Wraps \c mysql_set_server_option() in C API. bool set_option(enum_mysql_set_option msoption) { error_message_.clear(); return !mysql_set_server_option(&mysql_, msoption); } #endif /// \brief Set MySQL C API connection option /// /// Manipulates the MYSQL.client_flag bit mask. This allows these /// flags to be treated the same way as any other connection option, /// even though the C API handles them differently. bool set_option(unsigned int option, bool arg); /// \brief Same as set_option(), except that it won't override /// a previously-set option. bool set_option_default(Option* o) { const std::type_info& ti = typeid(o); for (OptionList::const_iterator it = applied_options_.begin(); it != applied_options_.end(); ++it) { if (typeid(*it) == ti) { delete o; return ""; // option of this type already set } } return set_option(o); } /// \brief Ask database server to shut down. /// /// User must have the "shutdown" privilege. /// /// Wraps \c mysql_shutdown() in the MySQL C API. bool shutdown(); /// \brief Returns the database server's 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. /// /// Wraps \c mysql_stat() in the MySQL C API. std::string server_status() { error_message_.clear(); return mysql_stat(&mysql_); } /// \brief Saves the results of the query just execute()d in memory /// and returns a pointer to the MySQL C API data structure the /// results are stored in. /// /// \sa use_result() /// /// Wraps \c mysql_store_result() in the MySQL C API. MYSQL_RES* store_result() { error_message_.clear(); return mysql_store_result(&mysql_); } /// \brief Returns true if MySQL++ and the underlying MySQL C API /// library were both compiled with thread awareness. /// /// This is based in part on a MySQL C API function /// mysql_thread_safe(). We deliberately don't call this wrapper /// thread_safe() because it's a misleading name: linking to /// thread-aware versions of the MySQL++ and C API libraries doesn't /// automatically make your program "thread-safe". See the /// <a href="../userman/threads.html">chapter on threads</a> in the /// user manual for more information and guidance. static bool thread_aware(); /// \brief Tells the underlying MySQL C API library that this thread /// is done using the library. /// /// This exists because the MySQL C API library allocates some per-thread /// memory which it doesn't release until you call this. static void thread_end() { #if MYSQL_VERSION_ID > 40000 // only in MySQL v4.0 + mysql_thread_end(); #endif } /// \brief Returns the MySQL server thread ID for this connection /// /// This has nothing to do with threading on the client side. It's /// a server-side thread ID, to be used with kill(). unsigned long thread_id() { error_message_.clear(); return mysql_thread_id(&mysql_); } /// \brief Tells the underlying C API library that the current /// thread will be using the library's services. /// /// \retval True if there was no problem /// /// The MySQL++ user manual's <a href="../userman/threads.html">chapter /// on threads</a> details two major strategies for dealing with /// connections in the face of threads. If you take the simpler /// path, creating one DBDriver object per thread, it is never /// necessary to call this function; the underlying C API will call it /// for you when you establish the first database server connection /// from that thread. If you use a more complex connection /// management strategy where it's possible for one thread to /// establish a connection that another thread uses, you must call /// this from each thread that can use the database before it creates /// any MySQL++ objects. If you use a DBDriverPool object, this /// applies; DBDriverPool isn't smart enough to call this for you, /// and the MySQL C API won't do it, either. static bool thread_start() { #if MYSQL_VERSION_ID > 40000 // only in MySQL v4.0 + return !mysql_thread_init(); #else return false; #endif } /// \brief Returns a result set from the last-executed query which /// we can walk through in linear fashion, which doesn't store all /// result sets in memory. /// /// \sa store_result /// /// Wraps \c mysql_use_result() in the MySQL C API. MYSQL_RES* use_result() { error_message_.clear(); return mysql_use_result(&mysql_); } protected: /// \brief Does things common to both connect() overloads, before /// each go and establish the connection in their different ways. bool connect_prepare(); /// \brief Common implementation of set_option(Option*) and the /// delayed option setting code in connect_prepare() bool set_option_impl(Option* o); private: /// \brief Data type of the list of applied connection options typedef std::deque<Option*> OptionList; /// \brief Iterator into an OptionList typedef OptionList::iterator OptionListIt; /// \brief Hidden assignment operator; we don't want to be copied /// that way. What would it mean? DBDriver& operator=(const DBDriver&); MYSQL mysql_; bool is_connected_; OptionList applied_options_; OptionList pending_options_; mutable std::string error_message_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_DBDRIVER_H) |
Deleted lib/defs.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/exceptions.h.
1 2 3 4 5 6 7 | /// \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. /*********************************************************************** | | | | | | | > > | | 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 | /// \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-2001 by MySQL AB, and (c) 2004-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_EXCEPTIONS_H) #define MYSQLPP_EXCEPTIONS_H #include "options.h" #include <exception> #include <string> #include <sstream> #include <typeinfo> 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_) { |
︙ | ︙ | |||
82 83 84 85 86 87 88 | /// \brief explanation of why exception was thrown std::string what_; }; /// \brief Exception thrown when a bad type conversion is attempted. | | | < < > > > > | 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 | /// \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 |
︙ | ︙ | |||
150 151 152 153 154 155 156 | /// \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. | | | | | | > > > > | | > > > > > > > | | < | | < | | > > > | < > | < | < | < < < | | | < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > | | > > > | | > > > > > > > > > > > > > > | | > > > | | > < | > > | > > > | | < | | < < | < < < < < < < < < < < < < < < < | < < < < < < | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 | /// \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 database 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 an object with operator [] or an /// at() method gets called with a bad index. class MYSQLPP_EXPORT BadIndex : public Exception { public: /// \brief Create exception object /// /// \param what type of object bad index tried on /// \param bad_index index value the container didn't like /// \param max_index largest legal index value for container explicit BadIndex(const char* what, int bad_index, int max_index) : Exception() { std::ostringstream outs; outs << "Index " << bad_index << " on " << what << " out of range, max legal index is " << max_index; what_ = outs.str(); } /// \brief Destroy exception ~BadIndex() throw() { } }; /// \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, const std::type_info& ti) : Exception(w), ti_(ti) { } /// \brief Create exception object, taking C++ string explicit BadOption(const std::string& w, const std::type_info& ti) : Exception(w), ti_(ti) { } /// \brief Return type information about the option that failed /// /// Because each option has its own C++ type, this lets you /// distinguish among BadOption exceptions programmatically. const std::type_info& what_option() const { return ti_; } private: const std::type_info& ti_; }; /// \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 something goes wrong in processing a /// "use" query. class MYSQLPP_EXPORT UseQueryError : public Exception { public: /// \brief Create exception object explicit UseQueryError(const char* w = "") : Exception(w) { } }; /// \brief Exception thrown when the database server encounters a problem /// while processing your query. /// /// Unlike most other MySQL++ exceptions, which carry just an error /// message, this type carries an error number to preserve /// Connection::errnum()'s return value at the point the exception is /// thrown. We do this because when using the Transaction class, the /// rollback process that occurs during stack unwinding issues a query /// to the database server, overwriting the error value. This rollback /// should always succeed, so this effect can fool code that relies on /// Connection::errnum() into believing that there was no error. /// /// Beware that in older versions of MySQL++, this was effectively the /// generic exception type. (This is most especially true in v1.7.x, /// but it continued to a lesser extent through the v2.x series.) When /// converting old code to new versions of MySQL++, it's therefore /// possible to get seemingly "new" exceptions thrown, which could crash /// your program if you don't also catch a more generic type like /// mysqlpp::Exception or std::exception. class MYSQLPP_EXPORT BadQuery : public Exception { public: /// \brief Create exception object /// /// \param w explanation for why the exception was thrown /// \param e the error number from the underlying database API explicit BadQuery(const char* w = "", int e = 0) : Exception(w), errnum_(e) { } /// \brief Create exception object /// /// \param w explanation for why the exception was thrown /// \param e the error number from the underlying database API explicit BadQuery(const std::string& w, int e = 0) : Exception(w), errnum_(e) { } /// \brief Return the error number corresponding to the error /// message returned by what() /// /// This may return the same value as Connection::errnum(), but not /// always. See the overview documentation for this class for the /// reason for the difference. int errnum() const { return errnum_; } private: int errnum_; ///< error number associated with execption }; /// \brief Exception thrown when there is a problem related to the /// database server connection. /// /// This is thrown not just on making the connection, but also on /// shutdown and when calling certain of Connection's methods that /// require a connection when there isn't one. class MYSQLPP_EXPORT ConnectionFailed : public Exception { public: /// \brief Create exception object /// /// \param w explanation for why the exception was thrown /// \param e the error number from the underlying database API explicit ConnectionFailed(const char* w = "", int e = 0) : Exception(w), errnum_(e) { } /// \brief Return the error number corresponding to the error /// message returned by what(), if any. /// /// If the error number is 0, it means that the error message /// doesn't come from the underlying database API, but rather from /// MySQL++ itself. This happens when an error condition is /// detected up at this higher level instead of letting the /// underlying database API do it. int errnum() const { return errnum_; } private: int errnum_; ///< error number associated with execption }; /// \brief Exception thrown when the program tries to select a new /// database and the database server refuses for some reason. class MYSQLPP_EXPORT DBSelectionFailed : public Exception { public: /// \brief Create exception object /// /// \param w explanation for why the exception was thrown /// \param e the error number from the underlying database API explicit DBSelectionFailed(const char* w = "", int e = 0) : Exception(w), errnum_(e) { } /// \brief Return the error number corresponding to the error /// message returned by what(), if any. /// /// If the error number is 0, it means that the error message /// doesn't come from the underlying database API, but rather from /// MySQL++ itself. This happens when an error condition is /// detected up at this higher level instead of letting the /// underlying database API do it. int errnum() const { return errnum_; } private: int errnum_; ///< error number associated with execption }; /// \brief Exception thrown when a BeecryptMutex object fails. class MYSQLPP_EXPORT MutexFailed : public Exception { public: /// \brief Create exception object explicit MutexFailed(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) { } }; /// \brief Used within MySQL++'s test harness only. class MYSQLPP_EXPORT SelfTestFailed : public Exception { public: /// \brief Create exception object explicit SelfTestFailed(const std::string& w) : Exception(w) { } }; /// \brief Thrown from the C++ to SQL data type conversion routine when /// it can't figure out how to map the type. /// /// This exception is not optional. The only alternatives when this /// happens are equally drastic: basically, either iterate past the /// end of an array (crashing the program) or call assert() to crash /// the program nicely. At least this way you have some control over /// how your program ends. You can even ignore the error and keep on /// going: this typically happens when building a SQL query, so you can /// handle it just the same as if the subsequent query execution failed. class MYSQLPP_EXPORT TypeLookupFailed : public Exception { public: /// \brief Create exception object explicit TypeLookupFailed(const std::string& w) : Exception(w) { } }; /// \brief Exception thrown when an insert policy is too strict to /// create a valid INSERT statement. /// /// Thrown by Query::insertfrom() if it is unable to add VALUES /// to an empty query. This means the size threshold or max packet /// size of the policy is set too small. class MYSQLPP_EXPORT BadInsertPolicy : public Exception { public: /// \brief Create exception object explicit BadInsertPolicy(const std::string& w) : Exception(w) { } }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_EXCEPTIONS_H) |
Added lib/field.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 field.h /// \brief Declares the Field and Fields classes. /*********************************************************************** Copyright (c) 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_FIELD_H) #define MYSQLPP_FIELD_H #include "common.h" #include "type_info.h" #include <vector> namespace mysqlpp { /// \brief Class to hold information about a SQL field /// /// This is a cut-down version of MYSQL_FIELD, using MySQL++ and generic /// C++ types instead of the C types it uses, and hiding all fields /// behind accessors. It leaves out data members we have decided aren't /// very useful. Given a good argument, we're willing to mirror more of /// the fields; we just don't want to mirror the underlying structure /// slavishly for no benefit. class Field { public: /// \brief Create empty object Field() : length_(0), max_length_(0), flags_(0) { } /// \brief Create object from C API field structure Field(const MYSQL_FIELD* pf) : name_(pf->name), table_(pf->table), #if MYSQL_VERSION_ID > 40000 // only in 4.0 + db_(pf->db), #endif type_(pf->type, (pf->flags & UNSIGNED_FLAG) != 0, (pf->flags & NOT_NULL_FLAG) == 0), length_(pf->length), max_length_(pf->max_length), flags_(pf->flags) { } /// \brief Create object as a copy of another Field Field(const Field& other) : name_(other.name_), table_(other.table_), db_(other.db_), type_(other.type_), length_(other.length_), max_length_(other.max_length_), flags_(other.flags_) { } /// \brief Returns true if field auto-increments bool auto_increment() const { return flags_ & AUTO_INCREMENT_FLAG; } /// \brief Returns true if field is of some binary type bool binary_type() const { return flags_ & BINARY_FLAG; } /// \brief Returns true if field is of some BLOB type bool blob_type() const { return flags_ & BLOB_FLAG; } /// \brief Return the name of the database the field comes from const char* db() const { return db_.c_str(); } /// \brief Returns true if field is of an enumerated value type bool enumeration() const { return flags_ & ENUM_FLAG; } /// \brief Return the creation size of the field /// /// This is the number of bytes the field can hold, not how much is /// actually stored in the field on any particular row. size_t length() const { return length_; } /// \brief Return the maximum number of bytes stored in this field /// in any of the rows in the result set we were created from. size_t max_length() const { return max_length_; } /// \brief Returns true if field is part of a key bool multiple_key() const { return flags_ & MULTIPLE_KEY_FLAG; } /// \brief Return the field's name const char* name() const { return name_.c_str(); } #if defined(NO_DEFAULT_VALUE_FLAG) /// \brief Returns true if field has no default value bool no_default() const { return flags_ & NO_DEFAULT_VALUE_FLAG; } #endif /// \brief Returns true if field is part of a primary key bool primary_key() const { return flags_ & PRI_KEY_FLAG; } /// \brief Returns true if field is of some 'set' type bool set_type() const { return flags_ & SET_FLAG; } /// \brief Return the name of the table the field comes from const char* table() const { return table_.c_str(); } /// \brief Returns true if field's type is timestamp bool timestamp() const { return flags_ & TIMESTAMP_FLAG; } /// \brief Return information about the field's type const mysql_type_info& type() const { return type_; } /// \brief Returns true if field is part of a unique key bool unique_key() const { return flags_ & UNIQUE_KEY_FLAG; } /// \brief Returns true if field has the zerofill attribute bool zerofill() const { return flags_ & ZEROFILL_FLAG; } private: std::string name_; ///< the field's name std::string table_; ///< name of table field comes from std::string db_; ///< name of database field comes from mysql_type_info type_; ///< info about the field's type size_t length_; ///< creation size of column size_t max_length_; ///< size of largest item in column in result set unsigned int flags_; ///< DB engine-specific set of bit flags }; /// \brief The list-of-Fields type typedef std::vector<Field> Fields; } // end namespace mysqlpp #endif // !defined(MYSQLPP_FIELD_H) |
Changes to lib/field_names.cpp.
1 2 3 | /*********************************************************************** field_names.cpp - Implements the FieldNames class. | | | | | | > | > > > | | | | > > | | > > > > > > > > > > | > > > | 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 | /*********************************************************************** field_names.cpp - Implements the FieldNames class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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" #include <algorithm> namespace mysqlpp { namespace internal { extern void str_to_lwr(std::string& s); } void FieldNames::init(const ResultBase* res) { size_t num = res->num_fields(); reserve(num); for (size_t i = 0; i < num; i++) { push_back(res->fields().at(i).name()); } } unsigned int FieldNames::operator [](const std::string& s) const { std::string temp1(s); internal::str_to_lwr(temp1); for (const_iterator it = begin(); it != end(); ++it) { std::string temp2(*it); internal::str_to_lwr(temp2); if (temp2.compare(temp1) == 0) { return it - begin(); } } return end() - begin(); } } // end namespace mysqlpp |
Changes to lib/field_names.h.
1 2 3 4 | /// \file field_names.h /// \brief Declares a class to hold a list of field names. /*********************************************************************** | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /// \file field_names.h /// \brief Declares a class to hold a list of field names. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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. |
︙ | ︙ | |||
24 25 26 27 28 29 30 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_FIELD_NAMES_H #define MYSQLPP_FIELD_NAMES_H | < < < | > > | > | > > > > > > > | > | | 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 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_FIELD_NAMES_H #define MYSQLPP_FIELD_NAMES_H #include <string> #include <vector> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT ResultBase; #endif /// \brief Holds a list of SQL field names class FieldNames : public std::vector<std::string> { public: /// \brief Default constructor FieldNames() { } /// \brief Copy constructor FieldNames(const FieldNames& other) : std::vector<std::string>() { assign(other.begin(), other.end()); } /// \brief Create field name list from a result set FieldNames(const ResultBase* res) : std::vector<std::string>() { 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 ResultBase* res) { init(res); return *this; } /// \brief Insert \c i empty field names at beginning of list FieldNames& operator =(int i) |
︙ | ︙ | |||
81 82 83 84 85 86 87 | /// \brief Get the name of a field given its index, in const /// context. const std::string& operator [](int i) const { return at(i); } | | | | > | > > > > | > > > | | 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 | /// \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 name of a field given its index. std::string& operator [](size_type i) { return at(i); } /// \brief Get the name of a field given its index, in const /// context. const std::string& operator [](size_type i) const { return at(i); } /// \brief Get the index number of a field given its name unsigned int operator [](const std::string& s) const; private: void init(const ResultBase* res); }; } // end namespace mysqlpp #endif |
Changes to lib/field_types.cpp.
1 2 3 | /*********************************************************************** field_types.cpp - Implements the FieldTypes class. | | | | | | | | | | | 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-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.txt 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 ResultBase* res) { size_t num = res->num_fields(); reserve(num); for (size_t i = 0; i < num; i++) { push_back(res->field(unsigned(i)).type()); } } } // end namespace mysqlpp |
Changes to lib/field_types.h.
1 2 3 4 5 | /// \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 | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | /// \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 |
︙ | ︙ | |||
30 31 32 33 34 35 36 | #include "type_info.h" #include <vector> namespace mysqlpp { | > > | > | | < < < < < < < < < < < < < | | 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 | #include "type_info.h" #include <vector> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT ResultBase; #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 ResultBase* 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 ResultBase* 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; } private: void init(const ResultBase* res); }; } // end namespace mysqlpp #endif |
Deleted lib/fields.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/fields.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added lib/insertpolicy.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 | /// \file insertpolicy.h /// \brief Declares the InsertPolicy classes. /// /// One creates an insert policy object to control how /// Query::insertfrom() builds queries from collections of SSQLS /// objects. Policy objects are what cause Query::insertfrom() to /// have different insertion behavior than Query::insert(iter, iter) /// /// These templates use a class called the AccessController, which /// is a stand-in for the mysqlpp::Transaction class and defaults to /// the Transaction class. Since some of the InsertPolicy objects /// (SizeThresholdInsertPolicy and MaxPacketInsertPolicy) may cause /// Query::insertfrom() to issue multiple SQL statements to perform /// the insertion of all the objects in the container, and a failure in /// one of these statements would leave the table in an indeterminate /// state, the whole operation is wrapped in a transaction. /// /// However, a transaction may not be desired if the calling code /// is managing transactions, or transactions are not being used for /// some other reason. In this case, the template can be instantiated /// with the NoTransaction class. It provides the complete Transaction /// class interface, while doing nothing. /// /// Where possible, you should use one of the provided insert /// policy classes, but you can define your own if you need a behavior /// that the provided set doesn't include. /// /// This file is not meant to be included in end-user code. It's /// included in Query's public interface, since it is only used with /// Query::insertfrom(). You access it as Query::InsertPolicy<T> /*********************************************************************** Copyright © 2008-2009 by AboveNet, Inc., and © 2009 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_INSERTPOLICY_H) #define MYSQLPP_INSERTPOLICY_H // Only allow these templates to be defined if they're being bodily // included into class Query's definition. They're in this separate // file only for claity, so they don't get lost among the other // definitions in class Query. Without this, Doxygen will pick them // up and treat them as a) outside namespace mysqlpp; and b) not member // templates of class Query. We also don't want end-users of the // library to #include this file in their own code; these templates // should only be used as mysqlpp::Query::*. #if defined(MYSQLPP_DEFINE_INSERT_POLICY_TEMPLATES) /// \brief An insert policy object that triggers a new INSERT /// statement after a given number of rows have been inserted. /// /// This policy is very lightweight, but is only reliable when you /// can predict the size of each INSERT in advance. The others do /// more processing to reduce the risk of unpredictable row sizes. template <class AccessController = Transaction> class MYSQLPP_EXPORT RowCountInsertPolicy { public: /// \brief Constructor RowCountInsertPolicy(unsigned int rows) : cur_rows_(0), max_rows_(rows) { } /// \brief Destructor ~RowCountInsertPolicy() { } /// \brief Can we add another object to the query? /// /// \retval true if the object is allowed to be added to the /// INSERT statement template <class RowT> bool can_add(int, const RowT&) { if (++cur_rows_ > max_rows_) { cur_rows_ = 0; return false; } else { return true; } } /// \brief Alias for our access controller type typedef AccessController access_controller; private: unsigned int cur_rows_; unsigned const int max_rows_; }; /// \brief An insert policy object that triggers a new INSERT statement /// after a size threshold for the length of the INSERT statement /// is exceeded. /// /// Although this insert policy isn't completely deterministic, it /// avoids building the VALUES expression for the SSQLS object /// passed in. template <class AccessController = Transaction> class MYSQLPP_EXPORT SizeThresholdInsertPolicy { public: /// \brief Constructor SizeThresholdInsertPolicy(int size) : size_(size) { } /// \brief Destructor ~SizeThresholdInsertPolicy() { } /// \brief Can we add another object to the query? /// /// \param size current length of the INSERT statement /// \param object the SSQLS object to be added /// /// \retval true if the object is allowed to be added to the /// INSERT statement template <class RowT> bool can_add(int size, const RowT& object) const { (void)object; // we don't use this, but other policies do return (size < size_); } /// \brief Alias for our access controller type typedef AccessController access_controller; private: int size_; }; /// \brief An insert policy object that triggers a new INSERT statement /// if the object to be added would cause the statement to exceed /// a maximum size. /// /// This differs from the SizeThresholdInsertPolicy in that it builds /// the VALUES expression and checks whether it would cause the /// length of the INSERT statement to exceed the maximum size. template <class AccessController = Transaction> class MYSQLPP_EXPORT MaxPacketInsertPolicy { public: /// \brief Constructor /// /// \param con connection object used for escaping text /// \param size the maximum allowed size for an INSERT /// statement MaxPacketInsertPolicy(Connection* con, int size) : conn_(con), size_(size) { } /// \brief Constructor /// /// This version does not use a Connection* so it will not be /// able to take the character set into account when escaping /// the text. /// /// \param size the maximum allowed size for an INSERT /// statement MaxPacketInsertPolicy(int size) : conn_(0), size_(size) { } /// \brief Destructor ~MaxPacketInsertPolicy() { } /// \brief Can we add another object to the query? /// /// \param size current length of the INSERT statement /// \param object the SSQLS object to be added /// /// \retval true if the object is allowed to be added to the /// INSERT statement template <class RowT> bool can_add(int size, const RowT& object) const { if (size < size_) { // Haven't hit size threshold yet, so see if this next // item pushes it over the line. SQLStream s(conn_); s << ",(" << object.value_list() << ")"; return (size_ - size) >= static_cast<int>(s.str().size()); } else { // Already too much in query buffer! return false; } } /// \brief Alias for our access controller type typedef AccessController access_controller; private: Connection* conn_; int size_; }; #endif // defined(MYSQLPP_DEFINE_INSERT_POLICY_TEMPLATES) #endif // !defined(MYSQLPP_INSERTPOLICY_H) |
Deleted lib/lockable.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/manip.cpp.
1 2 3 4 | /*********************************************************************** manip.cpp - Implements MySQL++'s various quoting/escaping stream manipulators. | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /*********************************************************************** manip.cpp - Implements MySQL++'s various quoting/escaping stream manipulators. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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. |
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #include "manip.h" #include "query.h" using namespace std; | > < < < < | < < < < < < < < < < < < < < < | | < | < | < < < | < < < > | < | | < | < < < < | < | < < < < < | | | | < < < < < < < < < < < < > > | | | | < | < < | > | < | < < < < < < | < < < | < > | < | | | < < < < | > | < < | < > | | > > > > | < < < < < < < < < | | < < | < < | < > | < < < > > | | | < < < | | | < < | | < < < < < | | < < < < | < > | < | < < | | < < < < < < < < | < | > > > > > < < > > | | | < < < < < < < < < < < < < < < < < < < < < | > > > | | > > > | < | | | < < < < < < < < < < < < < < | > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < | | < | > > > < | > | < < < < < < | > | | < > > | | < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < | | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < > | | < < | | > | > | > | < | < < < < < < | | < < < < | | < < | < | | | < < < | < < < | | | | | < < < | < | < < < < < < < < | | | < > | < < < < < < < | < < | < < < < < | < | < < < | | < < < < < | < < < < | | | < < | < < < > | | | < < | > | 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 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #include "manip.h" #include "query.h" #include "sqlstream.h" using namespace std; namespace mysqlpp { SQLQueryParms& operator <<(quote_type2 p, SQLTypeAdapter& in) { if (in.quote_q()) { string temp("'", 1), escaped; p.qparms->escape_string(&escaped, in.data(), in.length()); temp.append(escaped); temp.append("'", 1); *p.qparms << SQLTypeAdapter(temp, true); return *p.qparms; } else { in.set_processed(); return *p.qparms << in; } } ostream& operator <<(quote_type1 o, const SQLTypeAdapter& in) { Query* pq = dynamic_cast<Query*>(o.ostr); // If it's not a Query*, maybe it's a SQLStream*. SQLStream* psqls = pq ? 0 : dynamic_cast<SQLStream*>(o.ostr); // If it's a Query or a SQLStream, we'll be using unformatted output. if (pq || psqls) { if (in.quote_q()) o.ostr->put('\''); // Now, is escaping appropriate for source data type of 'in'? if (in.escape_q()) { string escaped; // If it's not a Query*, then it has to be a SQLStream. if (pq) { pq->escape_string(&escaped, in.data(), in.length()); } else { psqls->escape_string(&escaped, in.data(), in.length()); } o.ostr->write(escaped.data(), escaped.length()); } else { o.ostr->write(in.data(), in.length()); } if (in.quote_q()) o.ostr->put('\''); } else { // Some other stream type, so use formatted output. User // shouldn't be trying to use the quote manipulator, but // that's no reason to break their formatting. *o.ostr << string(in.data(), in.length()); } return *o.ostr; } ostream& operator <<(quote_only_type1 o, const SQLTypeAdapter& in) { Query* pq = dynamic_cast<Query*>(o.ostr); // If it's not a Query*, maybe it's a SQLStream*. SQLStream* psqls = pq ? 0 : dynamic_cast<SQLStream*>(o.ostr); // If it's a Query or SQLStream, use unformatted output if (pq || psqls) { if (in.quote_q()) o.ostr->put('\''); o.ostr->write(in.data(), in.length()); if (in.quote_q()) o.ostr->put('\''); } else { // Some other stream type, so use formatted output. User // shouldn't be trying to use this manipulator on a non-Query // stream, but that's no reason to break their formatting. *o.ostr << '\'' << in << '\''; } return *o.ostr; } ostream& operator <<(ostream& o, const SQLTypeAdapter& in) { if (dynamic_cast<Query*>(&o) || dynamic_cast<SQLStream*>(&o)) { // It's a Query or a SQLStream, so use unformatted output. return o.write(in.data(), in.length()); } else { // Some other stream type, so use formatted output. We do this // through the temporary so we remain null-friendly. return o << string(in.data(), in.length()); } } SQLQueryParms& operator <<(quote_only_type2 p, SQLTypeAdapter& in) { if (in.quote_q()) { string temp("'", 1); temp.append(in.data(), in.length()); temp.append("'", 1); return *p.qparms << SQLTypeAdapter(temp, true); } else { in.set_processed(); return *p.qparms << in; } } SQLQueryParms& operator <<(quote_double_only_type2 p, SQLTypeAdapter& in) { if (in.quote_q()) { string temp("\"", 1); temp.append(in.data(), in.length()); temp.append("\"", 1); return *p.qparms << SQLTypeAdapter(temp, true); } else { in.set_processed(); return *p.qparms << in; } } ostream& operator <<(quote_double_only_type1 o, const SQLTypeAdapter& in) { Query* pq = dynamic_cast<Query*>(o.ostr); // If it's not a Query*, maybe it's a SQLStream*. SQLStream* psqls = pq ? 0 : dynamic_cast<SQLStream*>(o.ostr); // If it's a Query or a SQLStream, use unformatted output if (pq || psqls) { if (in.quote_q()) o.ostr->put('"'); o.ostr->write(in.data(), in.length()); if (in.quote_q()) o.ostr->put('"'); } else { // Some other stream type, so use formatted output. User // shouldn't be trying to use this manipulator on a non-Query // stream, but that's no reason to break their formatting. *o.ostr << '"' << in << '"'; } return *o.ostr; } SQLQueryParms& operator <<(escape_type2 p, SQLTypeAdapter& in) { if (in.escape_q()) { string escaped; p.qparms->escape_string(&escaped, in.data(), in.length()); *p.qparms << SQLTypeAdapter(escaped, true); return *p.qparms; } else { in.set_processed(); return *p.qparms << in; } } ostream& operator <<(escape_type1 o, const SQLTypeAdapter& in) { Query* pq = dynamic_cast<Query*>(o.ostr); // If it's not a Query*, maybe it's a SQLStream*. SQLStream* psqls = pq ? 0 : dynamic_cast<SQLStream*>(o.ostr); if (pq || psqls) { // It's a Query or a SQLStream, so we'll be using unformatted output. // Now, is escaping appropriate for source data type of 'in'? if (in.escape_q()) { string escaped; // If it's not a Query*, then it has to be a SQLStream. if (pq) { pq->escape_string(&escaped, in.data(), in.length()); } else { psqls->escape_string(&escaped, in.data(), in.length()); } return o.ostr->write(escaped.data(), escaped.length()); } else { // It's not escaped, so just write the unformatted output return o.ostr->write(in.data(), in.length()); } } else { // Some other stream type, so use formatted output. User // shouldn't be trying to use the escape manipulator, but // that's no reason to break their formatting. return *o.ostr << string(in.data(), in.length()); } } SQLQueryParms& operator <<(do_nothing_type2 p, SQLTypeAdapter& in) { in.set_processed(); return *p.qparms << in; } ostream& operator <<(do_nothing_type1 o, const SQLTypeAdapter& in) { if (dynamic_cast<Query*>(o.ostr) || dynamic_cast<SQLStream*>(o.ostr)) { // It's a Query or a SQLStream, so use unformatted output return o.ostr->write(in.data(), in.length()); } else { // Some other stream type, so use formatted output. User // shouldn't be trying to use this manipulator on a non-Query // stream, but that's no reason to break their formatting. return *o.ostr << in; } } SQLQueryParms& operator <<(ignore_type2 p, SQLTypeAdapter& in) { return *p.qparms << in; } } // end namespace mysqlpp |
Changes to lib/manip.h.
1 | /// \file 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 | /// \file manip.h /// \brief Declares the Query stream manipulators and operators. /// /// These manipulators let you automatically quote elements or escape /// characters that are special in SQL when inserting them into a /// Query stream. They make it easier to build syntactically-correct /// SQL queries. /// /// This file also includes special \c operator<< definitions for a few /// key MySQL++ data types, since we know when to do automatic quoting /// and escaping for these types. This only works with Query streams, /// not regular std::ostreams, since we're only concerned with making /// correct SQL, not with presentation matters. /// /// test/test_manip.cpp exercises the mechanisms defined here. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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. |
︙ | ︙ | |||
38 39 40 41 42 43 44 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_MANIP_H #define MYSQLPP_MANIP_H | | < | < < < < < | < < | > > | | > > | | | | | < | | < < | | < < | < < | | < < < < | | < < < < < < < < < < < < < < < < < < < | < < < | < < < < < < | | < < < < < < | | < < < < < < | < | | < < < > | | 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 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_MANIP_H #define MYSQLPP_MANIP_H #include "common.h" #include "myset.h" #include "stadapter.h" #include <iostream> namespace mysqlpp { class SQLQueryParms; /// \enum quote_type0 /// \anchor quote_manip /// /// The standard 'quote' manipulator. It is the most widely useful /// manipulator in MySQL++. /// /// Insert this manipulator into a Query or SQLQueryParms stream to put /// single quotes around the next item in the stream, and escape any /// characters within it that are special in SQL, if the data type of /// the next item in the stream may require it. By contrast, Date /// objects only require escaping, not quoting, and integers never /// require either. The manipulators won't do work they know is not /// necessary to ensure syntactially-correct SQL. enum quote_type0 { quote ///< insert into a Query stream 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); } struct quote_type2 { SQLQueryParms *qparms; quote_type2(SQLQueryParms* p) : qparms(p) { } }; inline quote_type2 operator <<(SQLQueryParms& p, quote_type0 /* esc */) { return quote_type2(&p); } /// \brief Inserts a SQLTypeAdapter into a stream, quoted and escaped /// as appropriate to the data type the object was initialized from. MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_type2 p, SQLTypeAdapter& in); /// \brief Inserts a anything that can be converted to SQLTypeAdapter /// into a stream, quoted and escaped as needed if it's a Query stream MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o, const SQLTypeAdapter& in); /// \brief Inserts a SQLTypeAdapter into a non-Query stream. /// /// Although we know how to quote and escape SQLTypeAdapter objects, we /// only do that when inserting them into Query streams or when given an /// explicit manipulator because this feature is only intended to make /// it easier to build syntactically-correct SQL queries. MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o, const SQLTypeAdapter& in); template <class ST> inline std::ostream& operator <<(quote_type1 o, const Set<ST>& in) { return *o.ostr << '\'' << in << '\''; } #endif // !defined(DOXYGEN_IGNORE) |
︙ | ︙ | |||
227 228 229 230 231 232 233 | quote_only_type1(std::ostream* o) : ostr(o) { } }; | | | | | < < | < < < < < | | < < < < < < | | < < < | < | < < < < | < | < | < < < | < < < < < < < | < < < < > | > > > > > | | | | | < < | | < < < < < | | < < < < < < | | < < < < < < < < < < | | | < | < < < | | < < < < < < < < < < < | | | > > | > > | | | | | | | | < < < < < < < < < < < < < | | < | | | < < < < < | < < < < | < < < < < < < < < < < < < < < < < < < < < | 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 | 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); } /// \brief Inserts a SQLTypeAdapter 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.quote_q() /// flag. You can set it yourself, but SQLTypeAdapter's ctors should set /// it correctly for you. MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_only_type2 p, SQLTypeAdapter& in); MYSQLPP_EXPORT std::ostream& operator <<(quote_only_type1 o, const SQLTypeAdapter& 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. /// /// You might care to use it when you have MySQL's \c ANSI_QUOTES mode /// enabled. In that mode, single quotes are used only for string /// literals, and double quotes for identifiers. Otherwise, /// \c quote_only and \c quote are quite sufficient. 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); } /// \brief Inserts a SQLTypeAdapter 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.quote_q() /// flag. You can set it yourself, but SQLTypeAdapter's ctors should set /// it correctly for you. MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_double_only_type2 p, SQLTypeAdapter& in); MYSQLPP_EXPORT std::ostream& operator <<(quote_double_only_type1 o, const SQLTypeAdapter& 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. /// /// SQL-escapes following argument if it is of a data type that /// may require escaping when inserted into a Query or SQLQueryParms /// stream. This is useful with string types, for example, to avoid /// bad SQL when they contain special characters like single quotes, /// nulls, and newlines. Data types like integers which never benefit /// from escaping don't get run through the escaping routine even if /// you ask for it. 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 SQLTypeAdapter into a stream, escaping special SQL /// characters /// /// We actually only do the escaping if in.escape_q() returns true 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, SQLTypeAdapter& in); /// \brief Inserts anything that can be converted to SQLTypeAdapter into /// a stream, escaping special SQL characters as needed. MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o, const SQLTypeAdapter& in); /// \enum do_nothing_type0 /// \anchor do_nothing_manip /// /// The 'do_nothing' manipulator. /// |
︙ | ︙ | |||
567 568 569 570 571 572 573 | do_nothing_type1(std::ostream* o) : ostr(o) { } }; | | | | | < < < | | > > > | | | | 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 | 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); } MYSQLPP_EXPORT std::ostream& operator <<(do_nothing_type1 o, const SQLTypeAdapter& 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); } /// \brief Inserts a SQLTypeAdapter into a stream, with no escaping or /// quoting. MYSQLPP_EXPORT SQLQueryParms& operator <<(do_nothing_type2 p, SQLTypeAdapter& 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 }; |
︙ | ︙ | |||
633 634 635 636 637 638 639 | ignore_type2(SQLQueryParms* p) : qparms(p) { } }; | | | > > > | | | 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 | ignore_type2(SQLQueryParms* p) : qparms(p) { } }; inline ignore_type2 operator <<(SQLQueryParms& p, ignore_type0 /* esc */) { return ignore_type2(&p); } /// \brief Inserts a SQLTypeAdapter into a stream, with no escaping or /// quoting, and without marking the string as having been "processed". MYSQLPP_EXPORT SQLQueryParms& operator <<(ignore_type2 p, SQLTypeAdapter& in); #endif // !defined(DOXYGEN_IGNORE) } // end namespace mysqlpp #endif |
Changes to lib/myset.h.
1 2 3 4 5 | /// \file myset.h /// \brief Declares templates for generating custom containers used /// elsewhere in the library. /*********************************************************************** | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /// \file myset.h /// \brief Declares templates for generating custom containers used /// elsewhere in the library. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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. |
︙ | ︙ | |||
25 26 27 28 29 30 31 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_MYSET_H #define MYSQLPP_MYSET_H | | | < < < < < < < < < < < < | < < < < < < | | > > > | | | < < < < | < < < < | < < | < < < < < | > > | > > > > > | > | | < < | | > > > | > > | | > | | | | | > | < < | > > | | 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 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_MYSET_H #define MYSQLPP_MYSET_H #include "common.h" #include "mystring.h" #include "stream2string.h" #include <iostream> #include <set> 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 String& str) { set2container(str.c_str(), set_insert(this)); } /// \brief Convert this set's data to a string containing /// comma-separated items. operator std::string() const { return stream2string(*this); } /// \brief Return our value in std::string form std::string str() const { return *this; } }; /// \brief Inserts a Set object into a C++ stream template <class Container> inline std::ostream& operator <<(std::ostream& s, const Set<Container>& d) { typename Container::const_iterator i = d.begin(); typename Container::const_iterator e = d.end(); if (i != e) { while (true) { s << *i; if (++i == e) { break; } s << ","; } } return s; } #if !defined(DOXYGEN_IGNORE) // Doxygen will not generate documentation for this section. template <class Insert> void set2container(const char* str, Insert insert) { std::string temp; // Break str up using comma separators while (str && *str) { if (*str == ',') { insert(temp); temp.clear(); // Handle comma at end of string case if (*++str) { ++str; } } else { temp += *str++; } } // Save final element of set, if any if (temp.size()) { insert(temp); } } #endif // !defined(DOXYGEN_IGNORE) } // end namespace mysqlpp #endif |
Added 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 |
Changes to lib/mysql++.h.in.
1 2 3 | /// \file mysql++.h /// \brief The main MySQL++ header file. /// | | | | < < < < < | | | | | | | > | | < < > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > | 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 | /// \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-2001 by MySQL AB, and (c) 2004-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 /// get_library_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 "cpool.h" #include "query.h" #include "scopedconnection.h" #include "sql_types.h" #include "transaction.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(); // This won't exist forever! Wean yourself away from these as soon as // you can! #if defined(MYSQLPP_OLD_CLASS_NAMES) # define ColData String # define NullisBlank NullIsBlank # define NullisNull NullIsNull # define NullisZero NullIsZero # define ResNSel SimpleResult # define Result StoreQueryResult # define ResUse UseQueryResult # define SQLString SQLTypeAdapter #endif } // 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::Row, mysqlpp::StoreQueryResult, and mysqlpp::UseQueryResult. 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 |
︙ | ︙ |
Added lib/mystring.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 | /*********************************************************************** mystring.cpp - Implements the String class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "mystring.h" #include "query.h" #include <algorithm> #include <stdexcept> #include <string> namespace mysqlpp { char String::at(size_type pos) const { if (pos >= size()) { throw BadIndex("String", int(pos), int(size())); } else { return buffer_->data()[pos]; } } int String::compare(const String& other) const { if (other.buffer_) { return compare(0, std::max(length(), other.length()), other.buffer_->data()); } else { // Other object has no buffer, so we are greater unless empty or // we also have no buffer. return length() > 0 ? 1 : 0; } } int String::compare(const std::string& other) const { return compare(0, std::max(length(), other.length()), other.data()); } int String::compare(size_type pos, size_type num, std::string& other) const { return compare(pos, num, other.data()); } int String::compare(const char* other) const { return compare(0, std::max(length(), strlen(other)), other); } int String::compare(size_type pos, size_type num, const char* other) const { if (buffer_ && other) { return strncmp(data() + pos, other, num); } else if (!other) { // Initted and non-empty is "greater than" uninitted return length() > 0 ? 1 : 0; } else { // This object has no buffer, so we are less than other object // unless it is empty. return other[0] == '\0' ? 0 : -1; } } #if !defined(DOXYGEN_IGNORE) // Doxygen isn't smart enough to recognize these template // specializations. Maybe it's the MYSQLPP_EXPORT tags? template <> String String::conv(String) const { return *this; } template <> bool String::conv(bool) const { return *this; // delegate to operator bool } template <> std::string String::conv(std::string) const { return buffer_ ? std::string(data(), length()) : std::string(); } template <> Date String::conv(Date) const { return buffer_ ? Date(c_str()) : Date(); } template <> DateTime String::conv(DateTime) const { return buffer_ ? DateTime(c_str()) : DateTime(); } template <> Time String::conv(Time) const { return buffer_ ? Time(c_str()) : Time(); } #endif // !defined(DOXYGEN_IGNORE) const char* String::data() const { return buffer_ ? buffer_->data() : 0; } String::const_iterator String::end() const { return buffer_ ? buffer_->data() + buffer_->length() : 0; } bool String::escape_q() const { return buffer_ ? buffer_->type().escape_q() : false; } bool String::is_null() const { return buffer_ ? buffer_->is_null() : false; } void String::it_is_null() { if (buffer_) { buffer_->set_null(); } else { buffer_ = new SQLBuffer(0, 0, mysql_type_info::string_type, true); } } String::size_type String::length() const { return buffer_ ? buffer_->length() : 0; } bool String::quote_q() const { // If no buffer, it means we're an empty string, so we need to be // quoted to be expressed properly in SQL. return buffer_ ? buffer_->type().quote_q() : true; } void String::to_string(std::string& s) const { if (buffer_) { s.assign(buffer_->data(), buffer_->length()); } else { s.clear(); } } /// \brief Stream insertion operator for String objects /// /// This doesn't have anything to do with the automatic quoting and /// escaping you get when using SQLTypeAdapter with Query. The need to /// use String with Query should be rare, since String generally comes /// in result sets; it should only go back out as queries when using /// result data in a new query. Since SQLTypeAdapter has a conversion /// ctor for String, this shouldn't be a problem. It's just trading /// simplicity for a tiny bit of inefficiency in a rare case. And /// since String and SQLTypeAdapter can share a buffer, it's not all /// that inefficient anyway. std::ostream& operator <<(std::ostream& o, const String& in) { if (dynamic_cast<Query*>(&o)) { // We can just insert the raw data into the stream o.write(in.data(), in.length()); } else { // Can't guess what sort of stream it is, so convert the String // to a std::string so we can use the formatted output method. // To see why this is necessary, change it to use write() only // (unformatted output) and then run simple2: notice that the // columnar output formatting is wrecked. std::string temp; in.to_string(temp); o << temp; } return o; } } // end namespace mysqlpp |
Added lib/mystring.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 | /// \file mystring.h /// \brief Declares String class, MySQL++'s generic std::string-like /// class, used for holding data received from the database server. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_MYSTRING_H) #define MYSQLPP_MYSTRING_H #include "common.h" #include "datetime.h" #include "exceptions.h" #include "null.h" #include "sql_buffer.h" #include <string> #include <sstream> #include <limits> #include <stdlib.h> #include <string.h> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Doxygen will not generate documentation for this section. namespace detail { template<typename T, bool is_signed = std::numeric_limits<T>::is_signed> struct conv_promotion; template<> struct conv_promotion<float> { typedef double type; }; template<> struct conv_promotion<double> { typedef double type; }; # if !defined(NO_LONG_LONGS) template<> struct conv_promotion<unsigned long long> { typedef unsigned long long type; }; template<> struct conv_promotion<long long> { typedef long long type; }; # endif // preserve existing behaviour, char converted as signed long template<> struct conv_promotion<char> { typedef long type; }; // all other types use signed/unsigned long template<typename T> struct conv_promotion<T, true> { typedef long type; }; template<typename T> struct conv_promotion<T, false> { typedef unsigned long type; }; } // namespace detail class MYSQLPP_EXPORT SQLTypeAdapter; #endif // !defined(DOXYGEN_IGNORE) /// \brief A std::string work-alike that can convert itself from SQL /// text data formats to C++ data types. /// /// This class is an intermediate form for a SQL field, normally /// converted to a more useful native C++ type, not used directly. /// The only exception is in dealing with BLOB data, which stays in /// String form for efficiency and to avoid corrupting the data with /// facile conversions. Even then, it's best to use it through the /// typedef aliases like sql_blob in sql_types.h, in case we later /// change this underlying representation. /// /// String's implicit conversion operators let you can use these /// objects naturally: /// /// \code String("12.86") + 2.0 \endcode /// /// That will give you 14.86 (approximately) as you expect, but be /// careful not to get tripped up by C++'s type conversion rules. If /// you had said this instead: /// /// \code String("12.86") + 2 \endcode /// /// the result would be 14 because 2 is an integer, and C++'s type /// conversion rules put the String object in an integer context. /// /// You can disable the operator overloads that allow these things by /// defining MYSQLPP_NO_BINARY_OPERS. /// /// 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. class MYSQLPP_EXPORT 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 size_t size_type; /// \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 char* const_pointer; typedef const_pointer pointer; #endif // !defined(DOXYGEN_IGNORE) /// \brief Default constructor /// /// An object constructed this way is essentially useless, but /// sometimes you just need to construct a default object. String() : buffer_() { } /// \brief Copy ctor /// /// \param other the other String object /// /// This ctor only copies the pointer to the other String's data /// buffer and increments its reference counter. If you need a /// deep copy, use one of the ctors that takes a string. String(const String& other) : buffer_(other.buffer_) { } /// \brief Full constructor. /// /// \param str the string this object represents, or 0 for SQL null /// \param len the length of the string; embedded nulls are legal /// \param type MySQL type information for data within str /// \param is_null string represents a SQL null, not literal data /// /// The resulting object will contain a copy of the string buffer. /// The buffer will actually be 1 byte longer than the value given /// for \c len, to hold a null terminator for safety. We do this /// because this ctor may be used for things other than /// null-terminated C strings. (e.g. BLOB data) explicit String(const char* str, size_type len, mysql_type_info type = mysql_type_info::string_type, bool is_null = false) : buffer_(new SQLBuffer(str, len, type, is_null)) { } /// \brief C++ string version of full ctor /// /// \param str the string this object represents, or 0 for SQL null /// \param type MySQL type information for data within str /// \param is_null string represents a SQL null, not literal data /// /// The resulting object will contain a copy of the string buffer. explicit String(const std::string& str, mysql_type_info type = mysql_type_info::string_type, bool is_null = false) : buffer_(new SQLBuffer(str.data(), static_cast<size_type>(str.length()), type, is_null)) { } /// \brief Null-terminated C string version of full ctor /// /// \param str the string this object represents, or 0 for SQL null /// \param type MySQL type information for data within str /// \param is_null string represents a SQL null, not literal data /// /// The resulting object will contain a copy of the string buffer. explicit String(const char* str, mysql_type_info type = mysql_type_info::string_type, bool is_null = false) : buffer_(new SQLBuffer(str, static_cast<size_type>(strlen(str)), type, is_null)) { } /// \brief Destroy string ~String() { } /// \brief Assign raw data to this object /// /// This parallels the ctor with the same parameters, for when you /// must do a 2-step create, or when you want to reassign the data /// without creating a String temporary to get around the fact /// that operator=() can only take one parameter. void assign(const char* str, size_type len, mysql_type_info type = mysql_type_info::string_type, bool is_null = false) { buffer_ = new SQLBuffer(str, len, type, is_null); } /// \brief Assign a C++ string to this object /// /// This parallels the ctor with the same parameters, for when you /// must do a 2-step create, or when you want to reassign the data /// without creating a String temporary to get around the fact /// that operator=() can only take one parameter. void assign(const std::string& str, mysql_type_info type = mysql_type_info::string_type, bool is_null = false) { buffer_ = new SQLBuffer(str.data(), static_cast<size_type>(str.length()), type, is_null); } /// \brief Assign a C string to this object /// /// This parallels the ctor with the same parameters, for when you /// must do a 2-step create, or when you want to reassign the data /// without creating a String temporary to get around the fact /// that operator=() can only take one parameter. void assign(const char* str, mysql_type_info type = mysql_type_info::string_type, bool is_null = false) { buffer_ = new SQLBuffer(str, static_cast<size_type>(strlen(str)), type, is_null); } /// \brief Return a character within the string. /// /// \throw mysqlpp::BadIndex if the row is not initialized or there /// are less than \c i fields in the row. char at(size_type pos) const; /// \brief Return iterator pointing to the first character of /// the string const_iterator begin() const { return data(); } /// \brief Return a const pointer to the string data. const char* c_str() const { return data(); } #if defined(MYSQLPP_PLATFORM_VISUAL_CPP) // Squish VC++ warning about "possible loss of data" for these conversions # pragma warning(disable: 4244) #endif /// \brief Template for converting the column data to most any /// numeric data type. template <class Type> Type conv(Type) const { // Conversions are done using one of double/long/ulong/llong/ullong // so we call a helper function to do the work using that type. // This reduces the amount of template code instantiated. typedef typename detail::conv_promotion<Type>::type conv_type; return do_conv<conv_type>(typeid(Type).name()); } #if defined(MYSQLPP_PLATFORM_VISUAL_CPP) # pragma warning(default: 4244) #endif /// \brief Overload of conv() for types wrapped with Null<> /// /// If the String object was initialized with some string we /// recognize as a SQL null, we just return a copy of the global /// 'null' object converted to the requested type. Otherwise, we /// return the String's value wrapped in the Null<> template. template <class T, class B> Null<T, B> conv(Null<T, B>) const { if (is_null()) { return Null<T, B>(null); } else { return Null<T, B>(conv(T())); } } /// \brief Lexically compare this string to another. /// /// \param other string to compare against this one /// /// \see compare(size_type, size_type, const char*) int compare(const String& other) const; /// \brief Lexically compare this string to another. /// /// \param other string to compare against this one /// /// \see compare(size_type, size_type, const char*) int compare(const std::string& other) const; /// \brief Lexically compare this string to another. /// /// \param pos position within this string to begin comparison /// \param num maximum number of characters within this string to /// use in comparison /// \param other string to compare against this one /// /// \see compare(size_type, size_type, const char*) int compare(size_type pos, size_type num, std::string& other) const; /// \brief Lexically compare this string to another. /// /// \param other string to compare against this one /// /// \see compare(size_type, size_type, const char*) int compare(const char* other) const; /// \brief Lexically compare this string to another. /// /// \param pos position within this string to begin comparison /// \param num maximum number of characters within this string to /// use in comparison /// \param other string to compare against this one /// /// \retval < 0 if this string is lexically "less than" other /// \retval 0 if this string is equal to other /// \retval > 0 if this string is lexically "greater than" other int compare(size_type pos, size_type num, const char* other) const; /// \brief Raw access to the underlying buffer, with no C string /// interpretation. const char* data() const; /// \brief Returns true if size() == 0 bool empty() const { return size() == 0; } /// \brief Return iterator pointing to one past the last character /// of the string. const_iterator end() const; /// \brief Returns true if data of this type should be escaped, false /// otherwise. bool escape_q() const; /// \brief Returns true if this object is a SQL null. bool is_null() const; /// \brief Set a flag indicating that this object is a SQL null. void it_is_null(); /// \brief Return number of bytes in the string /// /// Note that this doesn't count the number of \b characters in the /// string. If your database is configured to use an 8-bit character /// set, this is a distinction without a difference. But, if you're /// using UTF-8 in the database, you will need to "widen" the UTF-8 /// data to use a fixed-size character set like UCS-2 and count the /// characters that way. You might use std::wstring, for example. size_type length() const; /// \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 Returns true if data of this type should be quoted, false /// otherwise. bool quote_q() const; /// \brief Return number of bytes in string /// /// See commentary for length() about the difference between bytes /// and characters. size_type size() const { return length(); } /// \brief Returns a copy of our internal string without leading /// blanks. void strip_leading_blanks(std::string& s) const { const char* pc = data(); if (pc) { size_type n = length(); while (n && (*pc == ' ')) { ++pc; --n; } s.assign(pc, n); } else { s.clear(); } } /// \brief Copies this object's data into a C++ string. /// /// If you know the data doesn't contain null characters (i.e. it's /// a typical string, not BLOB data), it's more efficient to just /// assign this object to anything taking \c const \c char*. (Or /// equivalently, call the \c data() method.) This copies a pointer /// to a buffer instead of copying the buffer's contents. void to_string(std::string& s) const; /// \brief Get this object's current MySQL type. mysql_type_info type() const { return buffer_ ? buffer_->type() : mysql_type_info::string_type; } /// \brief Assignment operator, from C++ string String& operator =(const std::string& rhs) { buffer_ = new SQLBuffer(rhs.data(), static_cast<size_type>(rhs.length()), mysql_type_info::string_type, false); return *this; } /// \brief Assignment operator, from C string /// /// This creates a copy of the entire string, not just a copy of /// the pointer. String& operator =(const char* str) { buffer_ = new SQLBuffer(str, static_cast<size_type>(strlen(str)), mysql_type_info::string_type, false); return *this; } /// \brief Assignment operator, from other String /// /// This only copies the pointer to the other String's data /// buffer and increments its reference counter. If you need a /// deep copy, assign a string to this object instead. String& operator =(const String& other) { buffer_ = other.buffer_; return *this; } /// \brief Equality comparison operator /// /// For comparing this object to any of the data types we have a /// compare() overload for. template <typename T> bool operator ==(const T& rhs) const { return compare(rhs) == 0; } /// \brief Equality comparison operator /// /// For checking object against MySQL++'s global \c null constant bool operator ==(const mysqlpp::null_type&) const { return is_null(); } /// \brief Inequality comparison operator /// /// For comparing this object to any of the data types we have a /// compare() overload for. template <typename T> bool operator !=(const T& rhs) const { return compare(rhs) != 0; } /// \brief Inequality comparison operator /// /// For checking object against MySQL++'s global \c null constant bool operator !=(const mysqlpp::null_type&) const { return !is_null(); } /// \brief Return a character within the string. /// /// This function is just syntactic sugar, wrapping the at() method. /// /// \throw mysqlpp::BadIndex if the string is not initialized or there /// are less than \c i fields in the string. char operator [](size_type pos) const { return at(pos); } /// \brief Returns a const char pointer to the object's raw data operator const char*() const { return 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 buffer_ ? atoi(c_str()) : false; } /// \brief Converts this object's string data to a mysqlpp::Date operator Date() const { return buffer_ ? Date(*this) : Date(); } /// \brief Converts this object's string data to a mysqlpp::DateTime operator DateTime() const { return buffer_ ? DateTime(*this) : DateTime(); } /// \brief Converts this object's string data to a mysqlpp::Time operator Time() const { return buffer_ ? Time(*this) : Time(); } /// \brief Converts the String to a nullable data type /// /// This is just an implicit version of conv(Null<T, B>) template <class T, class B> operator Null<T, B>() const { return conv(Null<T, B>()); } private: /// \brief Do the actual numeric conversion via @p Type. template <class Type> Type do_conv(const char* type_name) const { if (buffer_) { std::stringstream buf; buf.write(data(), static_cast<std::streamsize>(length())); buf.imbue(std::locale::classic()); // "C" locale Type num = Type(); if (buf >> num) { char c; if (!(buf >> c)) { // Nothing left in buffer, so conversion complete, // and thus successful. return num; } if (c == '.' && (typeid(Type) != typeid(float)) && (typeid(Type) != typeid(double))) { // Conversion stopped on a decimal point -- locale // doesn't matter to MySQL -- so only way to succeed // is if it's an integer and everything following // the decimal is inconsequential. c = '0'; // handles '.' at end of string while (buf >> c && c == '0') /* spin */ ; if (buf.eof() && c == '0') { return num; // only zeros after decimal point } } } else if (buf.eof()) { return num; // nothing to convert, return default value } throw BadConversion(type_name, data(), 0, length()); } else { return 0; } } RefCountedBuffer buffer_; ///< reference-counted data buffer friend class SQLTypeAdapter; }; MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o, const String& in); #if !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE) // Ignore this section is MYSQLPP_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) \ inline other operator opr (String x, other y) \ { return static_cast<conv>(x) opr y; } \ inline other operator opr (other x, String 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) // Squish more complaints about possible loss of data #if defined(MYSQLPP_PLATFORM_VISUAL_CPP) # pragma warning(disable: 4244) #endif 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(MYSQLPP_PLATFORM_VISUAL_CPP) # pragma warning(default: 4244) #endif #if !defined(NO_LONG_LONGS) operator_binary_int(longlong, longlong) operator_binary_int(ulonglong, ulonglong) #endif // !defined(NO_LONG_LONGS) #endif // !defined(MYSQLPP_NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE) #if !defined(DOXYGEN_IGNORE) // Doxygen isn't smart enough to recognize these template // specializations. Maybe it's the MYSQLPP_EXPORT tags? /// \brief Specialization of String::conv<Type>() for bool /// /// We can either do it this way, or define "\c strtob()" (string to /// bool, like \c strtol(), \c strtod()...) so we can use /// internal_string_to_number_proxy. template <> MYSQLPP_EXPORT bool String::conv(bool) const; /// \brief Specialization of String::conv<Type>() for String /// /// Yes, I hear you crying, "WTF!? Why does String need to be able to /// convert itself to String?" SSQLSes with BLOB columns, that's why. /// /// SSQLSes populate their data members from the raw field data by /// calling row["fieldname"].conv(). The raw field data is stored in a /// String, and the MySQL++ native BLOB type is String. Since we're /// dealing with generated code, we need this specialization which hand- /// written code wouldn't need. Prove the truth of this to yourself by /// removing this and counting how many pieces examples/cgi_jpeg.cpp /// breaks into. template <> MYSQLPP_EXPORT String String::conv(String) const; /// \brief Specialization of String::conv<Type>() for C++ strings template <> MYSQLPP_EXPORT std::string String::conv(std::string) const; /// \brief Specialization of String::conv<Type>() for mysqlpp::Date /// /// This is necessary because as of MySQL++ v3, Date no longer has an /// implicit conversion ctor from String, and SSQLS uses conv() instead /// of the C++ type conversion system anyway. template <> MYSQLPP_EXPORT Date String::conv(Date) const; /// \brief Specialization of String::conv<Type>() for mysqlpp::DateTime /// /// This is necessary because as of MySQL++ v3, DateTime no longer has /// an implicit conversion ctor from String, and SSQLS uses conv() /// instead of the C++ type conversion system anyway. template <> MYSQLPP_EXPORT DateTime String::conv(DateTime) const; /// \brief Specialization of String::conv<Type>() for mysqlpp::Time /// /// This is necessary because as of MySQL++ v3, Time no longer has an /// implicit conversion ctor from String, and SSQLS uses conv() instead /// of the C++ type conversion system anyway. template <> MYSQLPP_EXPORT Time String::conv(Time) const; #endif // !defined(DOXYGEN_IGNORE) } // end namespace mysqlpp #endif // !defined(MYSQLPP_MYSTRING_H) |
Changes to lib/noexceptions.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | /// 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. /*********************************************************************** | | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /// 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-2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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. |
︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_NOEXCEPTIONS_H #define MYSQLPP_NOEXCEPTIONS_H namespace mysqlpp { | > > > > | > > > > > > > > > > > > > > > > | | | | | | | | | 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 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_NOEXCEPTIONS_H #define MYSQLPP_NOEXCEPTIONS_H #include "common.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. /// /// Note that all methods are const even though some of them change our /// internal flag indicating whether exceptions should be thrown. This /// is justifiable because this is just an interface class, and it /// changes the behavior of our subclass literally only in exceptional /// conditions. This Jesuitical interpretation of "const" is required /// because you may want to disable exceptions on const subclass /// instances. /// /// If it makes you feel better about this, consider that the real /// change isn't within the const OptionalExceptions subclass instance. /// What changes is the code wrapping the method call on that instance /// that can optionally throw an exception. This outside code is in /// a better position to say what "const" means than the subclass /// instance. 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() const { exceptions_ = true; } /// \brief Disable exceptions from the object void disable_exceptions() const { 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) const { exceptions_ = e; } /// \brief Declare NoExceptions to be our friend so it can access /// our protected functions. friend class NoExceptions; private: mutable 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(const 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: const 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 |
Added lib/null.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 | /*********************************************************************** null.cpp - Defines a few things declared in null.h Copyright (c) 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "null.h" namespace mysqlpp { /// \brief "NULL" string constant used in many places within MySQL++ const std::string null_str("NULL"); } |
Changes to lib/null.h.
1 2 3 4 5 6 7 8 | /// \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. /*********************************************************************** | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /// \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-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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. |
︙ | ︙ | |||
31 32 33 34 35 36 37 38 39 40 41 42 43 | #ifndef MYSQLPP_NULL_H #define MYSQLPP_NULL_H #include "exceptions.h" #include <iostream> namespace mysqlpp { /// \brief The type of the global mysqlpp::null object. /// | > > > | | | | | > < | > > > > > > > | > > > > > > > > > > > > > | | | | | 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 | #ifndef MYSQLPP_NULL_H #define MYSQLPP_NULL_H #include "exceptions.h" #include <iostream> #include <string> namespace mysqlpp { extern const std::string null_str; ///< "NULL" string constant /// \brief The type of the global mysqlpp::null object. /// /// User code shouldn't declare variables of this type. Use the /// Null template instead. class MYSQLPP_EXPORT null_type { protected: #if !defined(DOXYGEN_IGNORE) // Doxygen will not generate documentation for this section. template <typename CannotConvertNullToAnyOtherDataType> operator CannotConvertNullToAnyOtherDataType() const { return CannotConvertNullToAnyOtherDataType(); } #endif // !defined(DOXYGEN_IGNORE) }; /// \brief Global 'null' instance. Use wherever you need a SQL null. /// /// SQL null is equal to nothing else. It is not the same as C++'s /// NULL value, it is not a Boolean false....it is unique. As such, if /// you use this in some other type context, you will get a compiler /// error saying something about \c CannotConvertNullToAnyOtherDataType. /// The only thing you can assign this object instance to is a variable /// of type Null<T>, and then only directly. Code like this does not /// work: /// /// \code /// int foo = return_some_value_for_foo(); /// mysqlpp::Null<int> bar = foo ? foo : mysqlpp::null; /// \endcode /// /// The compiler will try to convert mysqlpp::null to \c int to make /// all values in the conditional operation consistent, but this is /// not legal. Anyway, it's questionable code because it means you're /// using SQL null to mean the same thing as zero here. If zero is a /// special value, there's no reason to use SQL null. SQL null exists /// when every value for a particular column is legal and you need /// something that means "no legal value". 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; } 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) { |
︙ | ︙ | |||
139 140 141 142 143 144 145 | /// \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. | | > > | 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 | /// \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() : data(), is_null(false) { } /// \brief Initialize the object with a particular value. /// /// The object is marked as "not null" if you use this ctor. This |
︙ | ︙ | |||
184 185 186 187 188 189 190 | /// /// 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. | | > | | | | > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /// /// 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&) : data(), 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() const { if (is_null) { return 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&) { is_null = true; return *this; } /// \brief Do equality comparison of two nullable values /// /// Two null objects are equal, and null is not equal to not-null. /// If neither is null, we delegate to operator == for the base /// data type. bool operator ==(const Null<Type>& rhs) const { if (is_null && rhs.is_null) { return true; } else if (is_null != rhs.is_null) { return false; // one null, the other not } else { return data == rhs.data; } } /// \brief Do equality comparison against hard-coded SQL null /// /// This tells you the same thing as testing is_null member. bool operator ==(const null_type&) const { return is_null; } /// \brief Do inequality comparison of two nullable values bool operator !=(const Null<Type>& rhs) const { return !(*this == rhs); } /// \brief Do inequality comparison against hard-coded SQL null bool operator !=(const null_type& rhs) const { return !(*this == rhs); } /// \brief Do less-than comparison of two nullable values /// /// Two null objects are equal to each other, and null is less /// than not-null. If neither is null, we delegate to operator < /// for the base data type. bool operator <(const Null<Type>& rhs) const { if (is_null) { return !rhs.is_null; // less than only if RHS not null } else if (rhs.is_null) { return false; // non-null always greater than null } else { return data < rhs.data; // neither is null, so compare data } } /// \brief Do less-than comparison against hard-coded SQL null /// /// Always returns false because we can only be greater than or /// equal to a SQL null. bool operator <(const null_type&) const { return false; } }; #if !defined(DOXYGEN_IGNORE) // Doxygen will not generate documentation for this section. // Specialization the Null template for \c void |
︙ | ︙ |
Added lib/options.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 | /*********************************************************************** options.cpp - Implements the Option class hierarchy. Copyright (c) 2007-2009 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 "options.h" #include "dbdriver.h" namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // We're hiding all the Option subclass internals from Doxygen. All the // upper-level classes are documented fully, and each leaf class itself // is documented. It's just the ctors and set() methods we're refusing // to document over and over again. Option::Error CompressOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_COMPRESS) ? Option::err_NONE : Option::err_api_reject; } Option::Error ConnectTimeoutOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_CONNECT_TIMEOUT, &arg_) ? Option::err_NONE : Option::err_api_reject; } Option::Error FoundRowsOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(CLIENT_FOUND_ROWS, arg_) ? Option::err_NONE : Option::err_api_reject; } Option::Error GuessConnectionOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_GUESS_CONNECTION) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error IgnoreSpaceOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(CLIENT_IGNORE_SPACE, arg_) ? Option::err_NONE : Option::err_api_reject; } Option::Error InitCommandOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_INIT_COMMAND, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; } Option::Error InteractiveOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(CLIENT_INTERACTIVE, arg_) ? Option::err_NONE : Option::err_api_reject; } Option::Error LocalFilesOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(CLIENT_LOCAL_FILES, arg_) ? Option::err_NONE : Option::err_api_reject; } Option::Error LocalInfileOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_LOCAL_INFILE, &arg_) ? Option::err_NONE : Option::err_api_reject; } Option::Error MultiResultsOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 if (dbd->connected()) { return dbd->set_option(arg_ ? MYSQL_OPTION_MULTI_STATEMENTS_ON : MYSQL_OPTION_MULTI_STATEMENTS_OFF) ? Option::err_NONE : Option::err_api_reject; } else { return dbd->set_option(CLIENT_MULTI_RESULTS, arg_) ? Option::err_NONE : Option::err_api_reject; } #else return Option::err_api_limit; #endif } Option::Error MultiStatementsOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 if (dbd->connected()) { return dbd->set_option(arg_ ? MYSQL_OPTION_MULTI_STATEMENTS_ON : MYSQL_OPTION_MULTI_STATEMENTS_OFF) ? Option::err_NONE : Option::err_api_reject; } else { return dbd->set_option(CLIENT_MULTI_STATEMENTS, arg_) ? Option::err_NONE : Option::err_api_reject; } #else return Option::err_api_limit; #endif } Option::Error NamedPipeOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_NAMED_PIPE) ? Option::err_NONE : Option::err_api_reject; } Option::Error NoSchemaOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(CLIENT_NO_SCHEMA, arg_) ? Option::err_NONE : Option::err_api_reject; } #if MYSQL_VERSION_ID > 40000 // only in 4.0 + Option::Error ProtocolOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_PROTOCOL, &arg_) ? Option::err_NONE : Option::err_api_reject; } #endif Option::Error ReadDefaultFileOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_READ_DEFAULT_FILE, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; } Option::Error ReadDefaultGroupOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_READ_DEFAULT_GROUP, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; } Option::Error ReadTimeoutOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_READ_TIMEOUT, &arg_) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error ReconnectOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 50106 // Option fixed in this version to work correctly whether set before // connection comes up, or after return dbd->set_option(MYSQL_OPT_RECONNECT, &arg_) ? Option::err_NONE : Option::err_api_reject; #elif MYSQL_VERSION_ID >= 50013 // Between the time the option was created in 5.0.13 and when it was // fixed in 5.1.6, it only worked correctly if set after initial // connection. So, don't accept it if disconnected, even though API // does accept it; option gets reset when the connection comes up. return dbd->connected() ? dbd->set_option(MYSQL_OPT_RECONNECT, &arg_) ? Option::err_NONE : Option::err_api_reject : Option::err_disconnected; #else return Option::err_api_limit; #endif } Option::Error ReportDataTruncationOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 50003 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_REPORT_DATA_TRUNCATION, &arg_) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error SecureAuthOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_SECURE_AUTH, &arg_) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error SetCharsetDirOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_SET_CHARSET_DIR, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; } Option::Error SetCharsetNameOption::set(DBDriver* dbd) { return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_SET_CHARSET_NAME, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; } Option::Error SetClientIpOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_SET_CLIENT_IP, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error SharedMemoryBaseNameOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40100 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_SHARED_MEMORY_BASE_NAME, arg_.c_str()) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error SslOption::set(DBDriver* dbd) { #if defined(HAVE_MYSQL_SSL_SET) return dbd->connected() ? Option::err_connected : dbd->enable_ssl( key_.size() ? key_.c_str() : 0, cert_.size() ? cert_.c_str() : 0, ca_.size() ? ca_.c_str() : 0, capath_.size() ? capath_.c_str() : 0, cipher_.size() ? cipher_.c_str() : 0) ? Option::err_NONE : Option::err_api_reject; #else (void)dbd; return Option::err_api_limit; #endif } Option::Error UseEmbeddedConnectionOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_USE_EMBEDDED_CONNECTION) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error UseRemoteConnectionOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_USE_REMOTE_CONNECTION) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } Option::Error WriteTimeoutOption::set(DBDriver* dbd) { #if MYSQL_VERSION_ID >= 40101 return dbd->connected() ? Option::err_connected : dbd->set_option(MYSQL_OPT_WRITE_TIMEOUT, &arg_) ? Option::err_NONE : Option::err_api_reject; #else return Option::err_api_limit; #endif } #endif // !defined(DOXYGEN_IGNORE) } // end namespace mysqlpp |
Added lib/options.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 | /// \file options.h /// \brief Declares the Option class hierarchy, used to implement /// connection options in Connection and DBDriver classes. /// /// This is tied closely enough to DBDriver that there's a pure-OO /// argument that it should be declared as protected or private members /// within DBDriver. We do it outside DBDriver because there's so much /// of it. It'd overwhelm everything else that's going on in that class /// totally out of proprortion to the importance of options. /*********************************************************************** Copyright (c) 2007-2009 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_OPTIONS_H) #define MYSQLPP_OPTIONS_H #include "common.h" #include <deque> #include <string> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) class DBDriver; #endif //////////////////////////////////////////////////////////////////////// // Classes /// \brief Define abstract interface for all *Option subclasses. /// /// This is the base class for the mid-level interface classes that take /// arguments, plus the direct base for options that take no arguments. class MYSQLPP_EXPORT Option { public: /// \brief Types of option setting errors we can diagnose enum Error { err_NONE, ///< option was set successfully err_api_limit, ///< option not supported by underlying C API err_api_reject, ///< underlying C API returned error when setting option err_connected, ///< can't set the given option while connected err_disconnected///< can only set the given option while connected }; virtual ~Option() { } ///< Destroy object virtual Error set(DBDriver* dbd) = 0; ///< Apply option }; /// \brief Define abstract interface for all *Options that take a /// lone scalar as an argument. template <typename T> class MYSQLPP_EXPORT DataOption : public Option { public: typedef T ArgType; ///< Alias for template param protected: DataOption(const T& arg) : arg_(arg) { }///< Construct object T arg_; ///< The argument value }; typedef DataOption<unsigned> IntegerOption; ///< Option w/ int argument typedef DataOption<bool> BooleanOption; ///< Option w/ bool argument typedef DataOption<std::string> StringOption; ///< Option w/ string argument /// \brief Enable data compression on the connection class MYSQLPP_EXPORT CompressOption : public Option { #if !defined(DOXYGEN_IGNORE) public: CompressOption() : Option() { } private: Error set(DBDriver* dbd); #endif }; /// \brief Change Connection::connect() default timeout class MYSQLPP_EXPORT ConnectTimeoutOption : public IntegerOption { #if !defined(DOXYGEN_IGNORE) public: ConnectTimeoutOption(ArgType arg) : IntegerOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Make Query::affected_rows() return number of matched rows /// /// Default is to return number of \b changed rows. class MYSQLPP_EXPORT FoundRowsOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: FoundRowsOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Allow C API to guess what kind of connection to use /// /// This is the default. The option exists to override /// UseEmbeddedConnectionOption and UseEmbeddedConnectionOption. class MYSQLPP_EXPORT GuessConnectionOption : public Option { #if !defined(DOXYGEN_IGNORE) public: GuessConnectionOption() : Option() { } private: Error set(DBDriver* dbd); #endif }; /// \brief Allow spaces after function names in queries class MYSQLPP_EXPORT IgnoreSpaceOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: IgnoreSpaceOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Give SQL executed on connect class MYSQLPP_EXPORT InitCommandOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: InitCommandOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Assert that this is an interactive program /// /// Affects connection timeouts. class MYSQLPP_EXPORT InteractiveOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: InteractiveOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Enable LOAD DATA LOCAL statement class MYSQLPP_EXPORT LocalFilesOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: LocalFilesOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Enable LOAD LOCAL INFILE statement class MYSQLPP_EXPORT LocalInfileOption : public IntegerOption { #if !defined(DOXYGEN_IGNORE) public: LocalInfileOption(ArgType arg) : IntegerOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Enable multiple result sets in a reply class MYSQLPP_EXPORT MultiResultsOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: MultiResultsOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Enable multiple queries in a request to the server class MYSQLPP_EXPORT MultiStatementsOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: MultiStatementsOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Suggest use of named pipes class MYSQLPP_EXPORT NamedPipeOption : public Option { #if !defined(DOXYGEN_IGNORE) public: NamedPipeOption() : Option() { } private: Error set(DBDriver* dbd); #endif }; /// \brief Disable db.tbl.col syntax in queries class MYSQLPP_EXPORT NoSchemaOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: NoSchemaOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; #if MYSQL_VERSION_ID > 40000 // only in 4.0 + /// \brief Set type of protocol to use class MYSQLPP_EXPORT ProtocolOption : public IntegerOption { #if !defined(DOXYGEN_IGNORE) public: ProtocolOption(ArgType arg) : IntegerOption(arg) { } private: Error set(DBDriver* dbd); #endif }; #endif /// \brief Override use of my.cnf class MYSQLPP_EXPORT ReadDefaultFileOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: ReadDefaultFileOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Override use of my.cnf class MYSQLPP_EXPORT ReadDefaultGroupOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: ReadDefaultGroupOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Set timeout for IPC data reads class MYSQLPP_EXPORT ReadTimeoutOption : public IntegerOption { #if !defined(DOXYGEN_IGNORE) public: ReadTimeoutOption(ArgType arg) : IntegerOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Enable automatic reconnection to server class MYSQLPP_EXPORT ReconnectOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: ReconnectOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Set reporting of data truncation errors class MYSQLPP_EXPORT ReportDataTruncationOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: ReportDataTruncationOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Enforce use of secure authentication, refusing connection if /// not available class MYSQLPP_EXPORT SecureAuthOption : public BooleanOption { #if !defined(DOXYGEN_IGNORE) public: SecureAuthOption(ArgType arg) : BooleanOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Give path to charset definition files class MYSQLPP_EXPORT SetCharsetDirOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: SetCharsetDirOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Give name of default charset class MYSQLPP_EXPORT SetCharsetNameOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: SetCharsetNameOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Fake client IP address when connecting to embedded server class MYSQLPP_EXPORT SetClientIpOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: SetClientIpOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Set name of shmem segment for IPC class MYSQLPP_EXPORT SharedMemoryBaseNameOption : public StringOption { #if !defined(DOXYGEN_IGNORE) public: SharedMemoryBaseNameOption(ArgType arg) : StringOption(arg) { } private: Error set(DBDriver* dbd); #endif }; /// \brief Specialized option for handling SSL parameters. class MYSQLPP_EXPORT SslOption : public Option { public: /// \brief Create a set of SSL connection option parameters /// /// \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 /// /// This option replaces \c Connection::enable_ssl() from MySQL++ /// version 2. Now you can set this connection option just like any /// other. SslOption(const char* key = 0, const char* cert = 0, const char* ca = 0, const char* capath = 0, const char* cipher = 0) { if (key) key_.assign(key); if (cert) cert_.assign(cert); if (ca) ca_.assign(ca); if (capath) capath_.assign(capath); if (cipher) cipher_.assign(cipher); } private: std::string key_, cert_, ca_, capath_, cipher_; Error set(DBDriver* dbd); }; /// \brief Connect to embedded server in preference to remote server class MYSQLPP_EXPORT UseEmbeddedConnectionOption : public Option { #if !defined(DOXYGEN_IGNORE) public: UseEmbeddedConnectionOption() : Option() { } private: Error set(DBDriver* dbd); #endif }; /// \brief Connect to remote server in preference to embedded server class MYSQLPP_EXPORT UseRemoteConnectionOption : public Option { #if !defined(DOXYGEN_IGNORE) public: UseRemoteConnectionOption() : Option() { } private: Error set(DBDriver* dbd); #endif }; /// \brief Set timeout for IPC data reads class MYSQLPP_EXPORT WriteTimeoutOption : public IntegerOption { #if !defined(DOXYGEN_IGNORE) public: WriteTimeoutOption(ArgType arg) : IntegerOption(arg) { } private: Error set(DBDriver* dbd); #endif }; //////////////////////////////////////////////////////////////////////// // Typedefs /// \brief The data type of the list of connection options typedef std::deque<Option*> OptionList; /// \brief Primary iterator type into List typedef OptionList::const_iterator OptionListIt; } // end namespace mysqlpp #endif // !defined(MYSQLPP_OPTIONS_H) |
Deleted lib/platform.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/qparms.cpp.
1 | /*********************************************************************** | | | | 1 2 3 4 5 6 7 8 9 10 11 12 | /*********************************************************************** qparms.cpp - Implements the SQLQueryParms 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 |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #include "query.h" using namespace std; namespace mysqlpp { | > > > > > > | > > > > > > > > | | 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 | #include "query.h" using namespace std; namespace mysqlpp { size_t SQLQueryParms::escape_string(std::string* ps, const char* original, size_t length) const { return parent_ ? parent_->escape_string(ps, original, length) : 0; } size_t SQLQueryParms::escape_string(char* escaped, const char* original, size_t length) const { return parent_ ? parent_->escape_string(escaped, original, length) : 0; } SQLTypeAdapter& SQLQueryParms::operator [](const char* str) { if (parent_) { return operator [](parent_->parsed_nums_[str]); } throw ObjectNotInitialized("SQLQueryParms object has no parent!"); } const SQLTypeAdapter& SQLQueryParms::operator[] (const char* str) const { if (parent_) { return operator [](parent_->parsed_nums_[str]); } throw ObjectNotInitialized("SQLQueryParms object has no parent!"); } |
︙ | ︙ |
Changes to lib/qparms.h.
1 2 3 4 5 6 7 8 | /// \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. /*********************************************************************** | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /// \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-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.txt 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. |
︙ | ︙ | |||
28 29 30 31 32 33 34 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_QPARMS_H #define MYSQLPP_QPARMS_H | | > > | | | | | > | > | | < < < | | > > > | < | > | > > | | > > | > > | < | < | > > > | | > > > > | | | | | | | | | | | | | | | | | | > | 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 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ***********************************************************************/ #ifndef MYSQLPP_QPARMS_H #define MYSQLPP_QPARMS_H #include "stadapter.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<SQLTypeAdapter> { public: /// \brief Abbreviation so some of the declarations below don't /// span many lines. typedef const SQLTypeAdapter& sta; /// \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 Indirect access to Query::escape_string() /// /// \internal Needed by \c operator<<(Manip&, \c const \c T&) where /// \c Manip is used on a SQLQueryParms object. We'd have to make /// all these operators friends to give access to our internal Query /// object otherwise. /// /// \see Query::escape_string(std::string*, const char*, size_t) size_t escape_string(std::string* ps, const char* original = 0, size_t length = 0) const; /// \brief Indirect access to Query::escape_string() /// /// \see escape_string(std::string*, const char*, size_t) /// \see Query::escape_string(const char*, const char*, size_t) size_t escape_string(char* escaped, const char* original, size_t length) const; /// \brief Access element number n SQLTypeAdapter& operator [](size_type n) { if (n >= size()) { insert(end(), (n + 1) - size(), ""); } return std::vector<SQLTypeAdapter>::operator [](n); } /// \brief Access element number n const SQLTypeAdapter& operator [](size_type n) const { return std::vector<SQLTypeAdapter>::operator [](n); } /// \brief Access the value of the element with a key of str. SQLTypeAdapter& operator [](const char *str); /// \brief Access the value of the element with a key of str. const SQLTypeAdapter& operator [](const char *str) const; /// \brief Adds an element to the list SQLQueryParms& operator <<(const SQLTypeAdapter& str) { push_back(str); return *this; } /// \brief Adds an element to the list SQLQueryParms& operator +=(const SQLTypeAdapter& 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(sta a) { clear(); *this << a; } void set(sta a, sta b) { clear(); *this << a << b; } void set(sta a, sta b, sta c) { clear(); *this << a << b << c; } void set(sta a, sta b, sta c, sta d) { clear(); *this << a << b << c << d; } void set(sta a, sta b, sta c, sta d, sta e) { clear(); *this << a << b << c << d << e; } void set(sta a, sta b, sta c, sta d, sta e, sta f) { clear(); *this << a << b << c << d << e << f; } void set(sta a, sta b, sta c, sta d, sta e, sta f, sta g) { clear(); *this << a << b << c << d << e << f << g; } void set(sta a, sta b, sta c, sta d, sta e, sta f, sta g, sta h) { clear(); *this << a << b << c << d << e << f << g << h; } void set(sta a, sta b, sta c, sta d, sta e, sta f, sta g, sta h, sta i) { clear(); *this << a << b << c << d << e << f << g << h << i; } void set(sta a, sta b, sta c, sta d, sta e, sta f, sta g, sta h, sta i, sta j) { clear(); *this << a << b << c << d << e << f << g << h << i << j; } void set(sta a, sta b, sta c, sta d, sta e, sta f, sta g, sta h, sta i, sta j, sta 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(sta a, sta b, sta c, sta d, sta e, sta f, sta g, sta h, sta i, sta j, sta k, sta 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: |
︙ | ︙ | |||
228 229 230 231 232 233 234 | struct SQLParseElement { /// \brief Create object /// /// \param b the 'before' value /// \param o the 'option' value /// \param n the 'num' value | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | 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) |
Changes to lib/query.cpp.
1 2 3 | /*********************************************************************** query.cpp - Implements the Query class. | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /*********************************************************************** query.cpp - Implements the Query class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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. |
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 | 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 "connection.h" namespace mysqlpp { Query::Query(const Query& q) : | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > > | > > | > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | > | > > > > > | < < < | | < | < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > > > > | | 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 | 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 "dbdriver.h" #include "connection.h" namespace mysqlpp { // Force insertfrom() policy template instantiation. Required to make // VC++ happy. Query::RowCountInsertPolicy<Transaction> RowCountInsertPolicyI(0); Query::SizeThresholdInsertPolicy<Transaction> SizeThresholdInsertPolicyI(0); Query::MaxPacketInsertPolicy<Transaction> MaxPacketInsertPolicyI(0); Query::Query(Connection* c, bool te, const char* qstr) : #if defined(MYSQLPP_HAVE_STD__NOINIT) // prevents a double-init memory leak in native VC++ RTL (not STLport!) std::ostream(std::_Noinit), #else std::ostream(0), #endif OptionalExceptions(te), template_defaults(this), conn_(c), copacetic_(true) { // Set up our internal IOStreams string buffer init(&sbuffer_); // Insert passed query string into our string buffer, if given if (qstr) { sbuffer_.str(qstr); seekp(0, std::ios::end); // allow more insertions at end } // Override any global locale setting; we want to use the classic C // locale so we don't get weird things like thousands separators in // integers inserted into the query stream. imbue(std::locale::classic()); } Query::Query(const Query& q) : #if defined(MYSQLPP_HAVE_STD__NOINIT) // ditto above std::ostream(std::_Noinit), #else std::ostream(0), #endif OptionalExceptions(q.throw_exceptions()) { // Set up our internal IOStreams string buffer init(&sbuffer_); // See above for reason we override locale for Query streams. imbue(std::locale::classic()); // Copy the other query as best we can operator =(q); } ulonglong Query::affected_rows() { return conn_->driver()->affected_rows(); } int Query::errnum() const { return conn_->errnum(); } const char* Query::error() const { return conn_->error(); } size_t Query::escape_string(std::string* ps, const char* original, size_t length) const { if (conn_ && *conn_) { // Normal case return conn_->driver()->escape_string(ps, original, length); } else { // Should only happen in test/test_manip.cpp, since it doesn't // want to open a DB connection just to test the manipulators. return DBDriver::escape_string_no_conn(ps, original, length); } } size_t Query::escape_string(char* escaped, const char* original, size_t length) const { if (conn_ && *conn_) { // Normal case return conn_->driver()->escape_string(escaped, original, length); } else { // Should only happen in test/test_manip.cpp, since it doesn't // want to open a DB connection just to test the manipulators. return DBDriver::escape_string_no_conn(escaped, original, length); } } bool Query::exec(const std::string& str) { if ((copacetic_ = conn_->driver()->execute(str.data(), static_cast<unsigned long>(str.length()))) == true) { if (parse_elems_.size() == 0) { // Not a template query, so auto-reset reset(); } return true; } else if (throw_exceptions()) { throw BadQuery(error(), errnum()); } else { return false; } } SimpleResult Query::execute() { AutoFlag<> af(template_defaults.processing_); return execute(str(template_defaults)); } SimpleResult Query::execute(SQLQueryParms& p) { AutoFlag<> af(template_defaults.processing_); return execute(str(p)); } SimpleResult Query::execute(const SQLTypeAdapter& s) { if ((parse_elems_.size() == 2) && !template_defaults.processing_) { // We're a template query and this isn't a recursive call, so // take s to be a lone parameter for the query. We will come // back in here with a completed query, but the processing_ // flag will be set, allowing us to avoid an infinite loop. AutoFlag<> af(template_defaults.processing_); return execute(SQLQueryParms() << s); } else { // Take s to be the entire query string return execute(s.data(), s.length()); } } SimpleResult Query::execute(const char* str, size_t len) { if ((parse_elems_.size() == 2) && !template_defaults.processing_) { // We're a template query and this isn't a recursive call, so // take s to be a lone parameter for the query. We will come // back in here with a completed query, but the processing_ // flag will be set, allowing us to avoid an infinite loop. AutoFlag<> af(template_defaults.processing_); return execute(SQLQueryParms() << str << len ); } if ((copacetic_ = conn_->driver()->execute(str, len)) == true) { if (parse_elems_.size() == 0) { // Not a template query, so auto-reset reset(); } return SimpleResult(conn_, insert_id(), affected_rows(), info()); } else if (throw_exceptions()) { throw BadQuery(error(), errnum()); } else { return SimpleResult(); } } std::string Query::info() { return conn_->driver()->query_info(); } ulonglong Query::insert_id() { return conn_->driver()->insert_id(); } bool Query::more_results() { return conn_->driver()->more_results(); } Query& Query::operator=(const Query& rhs) { set_exceptions(rhs.throw_exceptions()); template_defaults = rhs.template_defaults; conn_ = rhs.conn_; copacetic_ = rhs.copacetic_; *this << rhs.sbuffer_.str(); parse_elems_ = rhs.parse_elems_; parsed_names_ = rhs.parsed_names_; parsed_nums_ = rhs.parsed_nums_; return *this; } Query::operator void*() const { return *conn_ && copacetic_ ? const_cast<Query*>(this) : 0; } void Query::parse() { std::string str = ""; char num[4]; std::string name; char* s = new char[sbuffer_.str().size() + 1]; memcpy(s, sbuffer_.str().data(), sbuffer_.str().size()); s[sbuffer_.str().size()] = '\0'; const char* s0 = s; while (*s) { if (*s == '%') { // Following might be a template parameter declaration... s++; if (*s == '%') { // Doubled percent sign, so insert literal percent sign. str += *s++; |
︙ | ︙ | |||
180 181 182 183 184 185 186 | else { num[2] = 0; } } else { num[1] = 0; } | | | | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | 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') { option = *s++; } // Is it a named parameter? if (*s == ':') { // Save all alphanumeric and underscore characters // following colon as parameter name. |
︙ | ︙ | |||
215 216 217 218 219 220 221 | std::string()); } parsed_names_[n] = name; parsed_nums_[name] = n; } // Finished parsing parameter; save it. | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | 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, |
︙ | ︙ | |||
238 239 240 241 242 243 244 | } parse_elems_.push_back(SQLParseElement(str, ' ', -1)); delete[] s0; } | | | | | > > > | | | < < < > | | > > > > > > > > | > | > > > | | > | < < < < < < < < | < | < < < < | | | > | > | | > > > > > > > | | | > > | > > > | | > | < > | | < < | < | > > > > | | | > > | | > | < < | < > | | | | | | | | < | > | > > > > > > > > > | > > | < < > > > | < | > | > | | > | > > > > > > > > | | > > | | < < < > | | | | | | > > > > > > | < > | | | | | < < < | | | | > > > | | | | | | | < > | < < > | | < | | | | | > > | > > | < | < | > > | > > > > > > > | > | < < > | | > > | | < < < < < < < < > > > > > > | < < | | < | | | > > > | | < | < > > > > > > | | > | > > | > > | < < | < < < < < | 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 | } parse_elems_.push_back(SQLParseElement(str, ' ', -1)); delete[] s0; } SQLTypeAdapter* Query::pprepare(char option, SQLTypeAdapter& S, bool replace) { if (S.is_processed()) { return &S; } if (option == 'q') { std::string temp(S.quote_q() ? "'" : "", S.quote_q() ? 1 : 0); if (S.escape_q()) { char *escaped = new char[S.size() * 2 + 1]; size_t len = conn_->driver()->escape_string(escaped, S.data(), static_cast<unsigned long>(S.size())); temp.append(escaped, len); delete[] escaped; } else { temp.append(S.data(), S.length()); } if (S.quote_q()) temp.append("'", 1); SQLTypeAdapter* ss = new SQLTypeAdapter(temp); if (replace) { S = *ss; S.set_processed(); delete ss; return &S; } else { return ss; } } else if (option == 'Q' && S.quote_q()) { std::string temp("'", 1); temp.append(S.data(), S.length()); temp.append("'", 1); SQLTypeAdapter *ss = new SQLTypeAdapter(temp); if (replace) { S = *ss; S.set_processed(); delete ss; return &S; } else { return ss; } } else { if (replace) { S.set_processed(); } 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) < template_defaults.size()) { c = &template_defaults; } else { *this << " ERROR"; throw BadParamCount( "Not enough parameters to fill the template."); } SQLTypeAdapter& param = (*c)[num]; if (param.is_null()) { MYSQLPP_QUERY_THISPTR << "NULL"; } else { SQLTypeAdapter* ss = pprepare(i->option, param, c->bound()); MYSQLPP_QUERY_THISPTR << *ss; if (ss != ¶m) { // 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(); template_defaults.clear(); } bool Query::result_empty() { return conn_->driver()->result_empty(); } StoreQueryResult Query::store() { AutoFlag<> af(template_defaults.processing_); return store(str(template_defaults)); } StoreQueryResult Query::store(SQLQueryParms& p) { AutoFlag<> af(template_defaults.processing_); return store(str(p)); } StoreQueryResult Query::store(const SQLTypeAdapter& s) { if ((parse_elems_.size() == 2) && !template_defaults.processing_) { // We're a template query and this isn't a recursive call, so // take s to be a lone parameter for the query. We will come // back in here with a completed query, but the processing_ // flag will be set, allowing us to avoid an infinite loop. AutoFlag<> af(template_defaults.processing_); return store(SQLQueryParms() << s); } else { // Take s to be the entire query string return store(s.data(), s.length()); } } StoreQueryResult Query::store(const char* str, size_t len) { if ((parse_elems_.size() == 2) && !template_defaults.processing_) { // We're a template query and this isn't a recursive call, so // take s to be a lone parameter for the query. We will come // back in here with a completed query, but the processing_ // flag will be set, allowing us to avoid an infinite loop. AutoFlag<> af(template_defaults.processing_); return store(SQLQueryParms() << str << len ); } MYSQL_RES* res = 0; if ((copacetic_ = conn_->driver()->execute(str, len)) == true) { res = conn_->driver()->store_result(); } if (res) { if (parse_elems_.size() == 0) { // Not a template query, so auto-reset reset(); } return StoreQueryResult(res, conn_->driver(), throw_exceptions()); } else { // Either result set is empty, or there was a problem executing // the query or storing its results. Since it's not an error to // use store() with queries that never return results (INSERT, // DELETE, CREATE, ALTER...) we need to figure out which case // this is. (You might use store() instead of execute() for // such queries when the query strings come from "outside".) copacetic_ = (conn_->errnum() == 0); if (copacetic_) { if (parse_elems_.size() == 0) { // Not a template query, so auto-reset reset(); } return StoreQueryResult(); } else if (throw_exceptions()) { throw BadQuery(error(), errnum()); } else { return StoreQueryResult(); } } } StoreQueryResult Query::store_next() { #if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 + DBDriver::nr_code rc = conn_->driver()->next_result(); if (rc == DBDriver::nr_more_results) { // There are more results, so return next result set. MYSQL_RES* res = conn_->driver()->store_result(); if (res) { return StoreQueryResult(res, conn_->driver(), 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(), errnum()); } else { return StoreQueryResult(); } } } else if (throw_exceptions()) { if (rc == DBDriver::nr_error) { throw BadQuery(error(), errnum()); } else if (conn_->errnum()) { throw BadQuery(error(), errnum()); } else { return StoreQueryResult(); // normal end-of-result-sets case } } else { return StoreQueryResult(); } #else return store(); #endif // MySQL v4.1+ } std::string Query::str(SQLQueryParms& p) { if (!parse_elems_.empty()) { proc(p); } return sbuffer_.str(); } UseQueryResult Query::use() { AutoFlag<> af(template_defaults.processing_); return use(str(template_defaults)); } UseQueryResult Query::use(SQLQueryParms& p) { AutoFlag<> af(template_defaults.processing_); return use(str(p)); } UseQueryResult Query::use(const SQLTypeAdapter& s) { if ((parse_elems_.size() == 2) && !template_defaults.processing_) { // We're a template query and this isn't a recursive call, so // take s to be a lone parameter for the query. We will come // back in here with a completed query, but the processing_ // flag will be set, allowing us to avoid an infinite loop. AutoFlag<> af(template_defaults.processing_); return use(SQLQueryParms() << s); } else { // Take s to be the entire query string return use(s.data(), s.length()); } } UseQueryResult Query::use(const char* str, size_t len) { if ((parse_elems_.size() == 2) && !template_defaults.processing_) { // We're a template query and this isn't a recursive call, so // take s to be a lone parameter for the query. We will come // back in here with a completed query, but the processing_ // flag will be set, allowing us to avoid an infinite loop. AutoFlag<> af(template_defaults.processing_); return use(SQLQueryParms() << str << len ); } MYSQL_RES* res = 0; if ((copacetic_ = conn_->driver()->execute(str, len)) == true) { res = conn_->driver()->use_result(); } if (res) { if (parse_elems_.size() == 0) { // Not a template query, so auto-reset reset(); } return UseQueryResult(res, conn_->driver(), throw_exceptions()); } else { // See comments in store() above for why we distinguish between // empty result sets and actual error returns here. copacetic_ = (conn_->errnum() == 0); if (copacetic_) { if (parse_elems_.size() == 0) { // Not a template query, so auto-reset reset(); } return UseQueryResult(); } else if (throw_exceptions()) { throw BadQuery(error(), errnum()); } else { return UseQueryResult(); } } } } // end namespace mysqlpp |
Changes to lib/query.h.
1 2 3 4 | /// \file query.h /// \brief Defines a class for building and executing SQL queries. /*********************************************************************** | | | | | | | | > | | | > < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | | < < < < < < < | | | < | < > | > > | > > > | < | | | | | > > > > > > > | > > | | < < > > > > > > | < < < < < < < < < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | > > > > > > | > > > > > > > | < | > > | > | | | > > > > | > | | < | < < < > | | < | | | < < < | > | > > > > | > > > > | < | < | | > | > | | | | > > | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | > | | | > > > > > > > > | > | > > > > > > > > > > > > > > > > | > > > > > > > > > | | | > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > | > > > > > > > > | > > | 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 | /// \file query.h /// \brief Defines a class for building and executing SQL queries. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2011 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_QUERY_H) #define MYSQLPP_QUERY_H #include "common.h" #include "exceptions.h" #include "noexceptions.h" #include "qparms.h" #include "querydef.h" #include "result.h" #include "row.h" #include "sqlstream.h" #include "stadapter.h" #include "transaction.h" #include <deque> #include <iomanip> #include <list> #include <map> #include <set> #include <vector> #ifdef HAVE_EXT_SLIST # include <ext/slist> #else # if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST) # include <slist> # endif #endif namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT Connection; class MYSQLPP_EXPORT Transaction; #endif /// \brief A class for building and executing SQL queries. /// /// 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 in either the form of a C or C++ string to one of the /// \link mysqlpp::Query::execute() exec*(), \endlink /// \link mysqlpp::Query::store() store*(), \endlink or use() methods. /// The query is executed immediately, and any results returned. /// /// For more complicated queries, it's often more convenient to build up /// the query string over several C++ statements using Query's stream /// interface. It works like any other C++ stream (\c std::cout, /// \c std::ostringstream, etc.) in that you can just insert things /// into the stream, building the query up piece by piece. When the /// query string is complete, you call the overloaded version of /// \link mysqlpp::Query::execute() exec*(), \endlink /// \link mysqlpp::Query::store() store*(), \endlink or /// \link mysqlpp::Query::use() use() \endlink 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. Having done that, you call one of the /// the many /// \link mysqlpp::Query::execute(const SQLTypeAdapter&) exec*(), \endlink /// \link mysqlpp::Query::store(const SQLTypeAdapter&) store*(), \endlink /// or \link mysqlpp::Query::use(const SQLTypeAdapter&) use() \endlink /// overloads that take SQLTypeAdapter objects. There are 25 of each by /// default, differing only in the number of STA objects they take. /// (See \c lib/querydef.pl if you need to change the limit, or /// \c examples/tquery2.cpp for a way around it that doesn't require /// changing the library.) Only the version taking a single STA object /// is documented below, as to document all of them would just be /// repetitive. For each Query method that takes a single STA object, /// there's a good chance there's a set of undocumented overloads that /// take more of them for the purpose of filling out a template query. /// /// See the user manual for more details about these options. class MYSQLPP_EXPORT Query : public std::ostream, public OptionalExceptions { public: // Bring in InsertPolicy template as part of this class's interface, // separate only in the sense that it's a self-contained concept. #define MYSQLPP_DEFINE_INSERT_POLICY_TEMPLATES #include "insertpolicy.h" #undef MYSQLPP_DEFINE_INSERT_POLICY_TEMPLATES /// \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 /// \param qstr an optional initial query string Query(Connection* c, bool te = true, const char* qstr = 0); /// \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 Return the number of rows affected by the last query ulonglong affected_rows(); /// \brief Return a SQL-escaped version of a character buffer /// /// \param ps pointer to C++ string to hold escaped version; if /// original is 0, also holds the original data to be escaped /// \param original if given, pointer to the character buffer to /// escape instead of contents of *ps /// \param length if both this and original are given, number of /// characters to escape instead of ps->length() /// /// \retval number of characters placed in *ps /// /// \see comments for escape_string(char*, const char*, size_t) /// and DBDriver::escape_string(std::string*, const char *, size_t) /// for further details. size_t escape_string(std::string* ps, const char* original = 0, size_t length = 0) const; /// \brief Return a SQL-escaped version of the given character /// buffer /// /// \param escaped character buffer to hold escaped version; must /// point to at least (length * 2 + 1) bytes /// \param original pointer to the character buffer to escape /// \param length number of characters to escape /// /// \retval number of characters placed in escaped /// /// DBDriver provides two versions of this method and /// Query::escape_string() calls the appropriate one based on whether /// or not a database connection is available. If the connection /// is available, it can call the DBDriver::escape_string() method. /// If there is no database connection available (normally only in /// testing), then DBDriver provides a static version of the function /// that doesn't use a database connection. /// /// \see comments for DBDriver::escape_string(char*, const char*, size_t), /// DBDriver::escape_string_no_conn(char*, const char*, size_t) /// for further details. size_t escape_string(char* escaped, const char* original, size_t length) const; /// \brief Get the last error number that was set. /// /// This just delegates to Connection::errnum(). Query has nothing /// extra to say, so use either, as makes sense in your program. int errnum() const; /// \brief Get the last error message that was set. /// /// This just delegates to Connection::error(). Query has nothing /// extra to say, so use either, as makes sense in your program. const char* error() const; /// \brief Returns information about the most recently executed /// query. std::string info(); /// \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. This /// applies to stored procedure calls because this function returns /// the ID generated by the last query, which was a CALL statement, /// and CALL doesn't generate IDs. You need to use LAST_INSERT_ID() /// to get the ID in this case. ulonglong insert_id(); /// \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 Test whether the object has experienced an error condition /// /// Allows for code constructs like this: /// /// \code /// Query q = conn.query(); /// .... use query object /// if (q) { /// ... no problems in using query object /// } /// else { /// ... an error has occurred /// } /// \endcode /// /// This method returns false if either the Query object or its /// associated Connection object has seen an error condition since /// the last operation. operator void*() const; /// \brief Returns true if the query object is not in a bad state /// /// This just returns the opposite of operator void*(), and is /// required only because basic_ios defines it, so we have to /// override it to get Query-specific behavior in code like this: /// /// \code if (!query) ... \endcode bool operator !() const { return !operator void*(); } /// \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. /// /// As of v3.0, Query objects auto-reset upon query execution unless /// you've set it up for making template queries. (It can't auto-reset /// in that situation, because it would forget the template info.) /// Therefore, the only time you must call this is if you have a Query /// object set up for making template queries, then want to build /// queries using one of the other methods. (Static strings, SSQLS, /// or the stream interface.) void reset(); /// \brief Returns true if the most recent result set was empty /// /// Wraps DBDriver::result_empty() bool result_empty(); /// \brief Get built query as a C++ string std::string str() { return str(template_defaults); } /// \brief Get built query as a C++ string with template query /// parameter substitution. /// /// \param arg0 the value to substitute for the first template query /// parameter; because SQLTypeAdapter implicitly converts from many /// different data types, this method is very flexible in what it /// accepts as a parameter. You shouldn't have to use the /// SQLTypeAdapter data type directly in your code. /// /// There many more overloads of this type (25 total, by default; /// see \c lib/querydef.pl), each taking one more SQLTypeAdapter object /// than the previous one. See the template query overview above /// for more about this topic. std::string str(const SQLTypeAdapter& arg0) { return str(SQLQueryParms() << arg0); } /// \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 Execute a built-up query /// /// Same as exec(), except that it uses the query string built up /// within the query object already instead of accepting a query /// string from the caller. /// /// \return true if query was executed successfully /// /// \sa exec(const std::string& str), execute(), store(), /// storein(), and use() bool exec() { return exec(str(template_defaults)); } /// \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 SimpleResult 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 SimpleResult status information about the query /// /// \sa exec(), store(), storein(), and use() SimpleResult execute(); /// \brief Execute template query using given parameters. /// /// This method should only be used by code that doesn't know, /// at compile time, how many parameters it will have. This is /// useful within the library, and also for code that builds /// template queries dynamically, at run time. /// /// \param p parameters to use in the template query. SimpleResult execute(SQLQueryParms& p); /// \brief Execute a query that returns no rows /// /// \param str if this object is set up as a template query, this is /// the value to substitute for the first template query parameter; /// else, it is the SQL query string to execute /// /// Because SQLTypeAdapter can be initialized from either a C string /// or a C++ string, this overload accepts query strings in either /// form. Beware, SQLTypeAdapter also accepts many other data types /// (this is its \e raison \e d'etre), so it will let you write code /// that compiles but results in bogus SQL queries. /// /// To support template queries, there many more overloads of this /// type (25 total, by default; see \c lib/querydef.pl), each taking /// one more SQLTypeAdapter object than the previous one. See the /// template query overview above for more about this topic. SimpleResult execute(const SQLTypeAdapter& str); /// \brief Execute query in a known-length string of characters. /// This can include null characters. /// /// Executes the query immediately, and returns the results. SimpleResult execute(const char* str, size_t len); /// \brief Execute a query that can return rows, with access to /// the rows in sequence /// /// 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 UseQueryResult object that can walk through result set serially /// /// \sa exec(), execute(), store() and storein() UseQueryResult use(); /// \brief Execute a template query that can return rows, with /// access to the rows in sequence /// /// This method should only be used by code that doesn't know, /// at compile time, how many parameters it will have. This is /// useful within the library, and also for code that builds /// template queries dynamically, at run time. /// /// \param p parameters to use in the template query. UseQueryResult use(SQLQueryParms& p); /// \brief Execute a query that can return rows, with access to /// the rows in sequence /// /// \param str if this object is set up as a template query, this is /// the value to substitute for the first template query parameter; /// else, it is the SQL query string to execute /// /// Because SQLTypeAdapter can be initialized from either a C string /// or a C++ string, this overload accepts query strings in either /// form. Beware, SQLTypeAdapter also accepts many other data types /// (this is its \e raison \e d'etre), so it will let you write code /// that compiles but results in bogus SQL queries. /// /// To support template queries, there many more overloads of this /// type (25 total, by default; see \c lib/querydef.pl), each taking /// one more SQLTypeAdapter object than the previous one. See the /// template query overview above for more about this topic. UseQueryResult use(const SQLTypeAdapter& str); /// \brief Execute a query that can return rows, with access to /// the rows in sequence /// /// This overload is for situations where you have the query in a /// C string and have its length already. If you want to execute /// a query in a null-terminated C string or have the query string /// in some other form, you probably want to call /// use(const SQLTypeAdapter&) instead. SQLTypeAdapter converts /// from plain C strings and other useful data types implicitly. UseQueryResult 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 StoreQueryResult object containing entire result set /// /// \sa exec(), execute(), storein(), and use() StoreQueryResult store(); /// \brief Store results from a template query using given parameters. /// /// This method should only be used by code that doesn't know, /// at compile time, how many parameters it will have. This is /// useful within the library, and also for code that builds /// template queries dynamically, at run time. /// /// \param p parameters to use in the template query. StoreQueryResult store(SQLQueryParms& p); /// \brief Execute a query that can return rows, returning all /// of the rows in a random-access container /// /// \param str if this object is set up as a template query, this is /// the value to substitute for the first template query parameter; /// else, it is the SQL query string to execute /// /// Because SQLTypeAdapter can be initialized from either a C string /// or a C++ string, this overload accepts query strings in either /// form. Beware, SQLTypeAdapter also accepts many other data types /// (this is its \e raison \e d'etre), so it will let you write code /// that compiles but results in bogus SQL queries. /// /// To support template queries, there many more overloads of this /// type (25 total, by default; see \c lib/querydef.pl), each taking /// one more SQLTypeAdapter object than the previous one. See the /// template query overview above for more about this topic. StoreQueryResult store(const SQLTypeAdapter& str); /// \brief Execute a query that can return rows, returning all /// of the rows in a random-access container /// /// This overload is for situations where you have the query in a /// C string and have its length already. If you want to execute /// a query in a null-terminated C string or have the query string /// in some other form, you probably want to call /// store(const SQLTypeAdapter&) instead. SQLTypeAdapter converts /// from plain C strings and other useful data types implicitly. StoreQueryResult 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 SQLTypeAdapter& query, Function fn) { mysqlpp::UseQueryResult 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 SQLTypeAdapter&, 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::UseQueryResult 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) { std::string query("select * from `"); query += ssqls.table(); query += '`'; mysqlpp::UseQueryResult 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 con 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& con, const SQLTypeAdapter& query, Function fn) { mysqlpp::UseQueryResult res = use(query); if (res) { mysqlpp::NoExceptions ne(res); while (mysqlpp::Row row = res.fetch_row()) { if (fn(row)) { con.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 SQLTypeAdapter&, Function), but /// it uses the SSQLS instance to construct a "select * from TABLE" /// query, using the table name field in the SSQLS. /// /// \param con 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& con, const SSQLS& ssqls, Function fn) { std::string query("select * from `"); query += ssqls.table(); query += '`'; mysqlpp::UseQueryResult res = use(query); if (res) { mysqlpp::NoExceptions ne(res); while (mysqlpp::Row row = res.fetch_row()) { if (fn(row)) { con.push_back(row); } } } return fn; } /// \brief Execute the query, conditionally storing each row in a /// container /// /// Just like store_if(Sequence&, const SQLTypeAdapter&, Function), but /// it uses the query string held by the Query object already /// /// \param con 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& con, Function fn) { mysqlpp::UseQueryResult res = use(); if (res) { mysqlpp::NoExceptions ne(res); while (mysqlpp::Row row = res.fetch_row()) { if (fn(row)) { con.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 |
︙ | ︙ | |||
398 399 400 401 402 403 404 | /// 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. /// | | | | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 | /// 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 StoreQueryResult object containing the next result set. StoreQueryResult 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 /// /// \sa exec(), execute(), store(), and use() template <class Sequence> void storein_sequence(Sequence& con) { storein_sequence(con, str(template_defaults)); } /// \brief Executes a query, storing the result rows in an STL /// sequence container. /// /// \param con the container to store the results in /// /// \param s if Query is set up as a template query, this is the value /// to substitute for the first template query parameter; else, the /// SQL query string /// /// There many more overloads of this type (25 total, by default; /// see \c lib/querydef.pl), each taking one more SQLTypeAdapter object /// than the previous one. See the template query overview above /// for more about this topic. template <class Sequence> void storein_sequence(Sequence& con, const SQLTypeAdapter& s) { if (UseQueryResult result = use(s)) { while (1) { MYSQL_ROW d = result.fetch_raw_row(); if (!d) break; Row row(d, &result, result.fetch_lengths(), throw_exceptions()); if (!row) break; con.push_back(typename Sequence::value_type(row)); } } else if (!result_empty()) { // Underlying MySQL C API returned an empty result for this // query, but it also says it should have returned // something. Reasons it can do that are given here: // http://dev.mysql.com/doc/refman/5.5/en/null-mysql-store-result.html // Regardless, it means the C library barfed, so we can't // just return an empty result set. copacetic_ = false; if (throw_exceptions()) { throw UseQueryError("Bogus empty result"); } } // else, it was *supposed* to return nothing, because query was // an INSERT, CREATE, etc. sort. So, leave con untouched. } /// \brief Execute template query using given parameters, storing /// the results in a sequence type container. /// /// This method should only be used by code that doesn't know, /// at compile time, how many parameters it will have. This is /// useful within the library, and also for code that builds /// template queries dynamically, at run time. /// /// \param con container that will receive the results /// \param p parameters to use in the template query. template <class Seq> void storein_sequence(Seq& con, SQLQueryParms& p) { storein_sequence(con, str(p)); } /// \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) { storein_set(con, str(template_defaults)); } /// \brief Executes a query, storing the result rows in an STL /// set-associative container. /// /// \param con the container to store the results in /// /// \param s if Query is set up as a template query, this is the value /// to substitute for the first template query parameter; else, the /// SQL query string /// /// There many more overloads of this type (25 total, by default; /// see \c lib/querydef.pl), each taking one more SQLTypeAdapter object /// than the previous one. See the template query overview above /// for more about this topic. template <class Set> void storein_set(Set& con, const SQLTypeAdapter& s) { if (UseQueryResult result = use(s)) { while (1) { MYSQL_ROW d = result.fetch_raw_row(); if (!d) break; Row row(d, &result, result.fetch_lengths(), throw_exceptions()); if (!row) break; con.insert(typename Set::value_type(row)); } } else if (!result_empty()) { // Underlying MySQL C API returned an empty result for this // query, but it also says it should have returned // something. Reasons it can do that are given here: // http://dev.mysql.com/doc/refman/5.5/en/null-mysql-store-result.html // Regardless, it means the C library barfed, so we can't // just return an empty result set. copacetic_ = false; if (throw_exceptions()) { throw UseQueryError("Bogus empty result"); } } // else, it was *supposed* to return nothing, because query was // an INSERT, CREATE, etc. sort. So, leave con untouched. } /// \brief Execute template query using given parameters, storing /// the results in a set type container. /// /// This method should only be used by code that doesn't know, /// at compile time, how many parameters it will have. This is /// useful within the library, and also for code that builds /// template queries dynamically, at run time. /// /// \param con container that will receive the results /// \param p parameters to use in the template query. template <class Set> void storein_set(Set& con, SQLQueryParms& p) { storein_set(con, str(p)); } /// \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 |
︙ | ︙ | |||
469 470 471 472 473 474 475 | /// 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> | | > > > > > > > > > > > > | | | | | | | | | | | | 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 | /// 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) { storein(con, str(template_defaults)); } /// \brief Store template query results into a container /// /// This method is not intended to be used directly. It is part /// of the call chain in processing calls to one of the many /// storein() overloads that take a container and one or more /// SQLTypeAdapter parameters. template <class T> void storein(T& con, SQLQueryParms& p) { storein(con, str(p)); } /// \brief Specialization of storein_sequence() for \c std::vector template <class T> void storein(std::vector<T>& con, const SQLTypeAdapter& s) { storein_sequence(con, s); } /// \brief Specialization of storein_sequence() for \c std::deque template <class T> void storein(std::deque<T>& con, const SQLTypeAdapter& s) { storein_sequence(con, s); } /// \brief Specialization of storein_sequence() for \c std::list template <class T> void storein(std::list<T>& con, const SQLTypeAdapter& 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 SQLTypeAdapter& 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 SQLTypeAdapter& 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 SQLTypeAdapter& 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 SQLTypeAdapter& s) { storein_set(con, s); } /// \brief Specialization of storein_set() for \c std::multiset template <class T> void storein(std::multiset<T>& con, const SQLTypeAdapter& 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 |
︙ | ︙ | |||
560 561 562 563 564 565 566 | 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 | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > | | | < | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | > | | > | | | | | < | | | | < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < | < | | < < < < < < | | < < < < < < | < < < < < | | < < < < < < < < < < < | | 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 | 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 insertfrom(), replace(), update() template <class Iter> Query& insert(Iter first, Iter last) { reset(); if (first != last) { // Build SQL for first item in the container. It's special // because we need the table name and field list. MYSQLPP_QUERY_THISPTR << std::setprecision(16) << "INSERT INTO `" << first->table() << "` (" << first->field_list() << ") VALUES (" << first->value_list() << ')'; // Now insert any remaining container elements. Be careful // hacking on the iterator use here: we want it to work // with containers providing only a forward iterator. Iter it = first; while (++it != last) { MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')'; } } return *this; } /// \brief Insert multiple new rows using an insert policy to /// control how the INSERT statements are created using /// items from an STL container. /// /// \param first iterator pointing to first element in range to /// insert /// \param last iterator pointing to one past the last element to /// insert /// \param policy insert policy object, see insertpolicy.h for /// details /// /// \sa insert() template <class Iter, class InsertPolicy> Query& insertfrom(Iter first, Iter last, InsertPolicy& policy) { bool success = true; bool empty = true; reset(); if (first == last) { return *this; // empty set! } typename InsertPolicy::access_controller ac(*conn_); for (Iter it = first; it != last; ++it) { if (policy.can_add(int(tellp()), *it)) { if (empty) { MYSQLPP_QUERY_THISPTR << std::setprecision(16) << "INSERT INTO `" << it->table() << "` (" << it->field_list() << ") VALUES ("; } else { MYSQLPP_QUERY_THISPTR << ",("; } MYSQLPP_QUERY_THISPTR << it->value_list() << ')'; empty = false; } else { // Execute what we've built up already, if there is anything if (!empty) { if (!exec()) { success = false; break; } empty = true; } // If we _still_ can't add, the policy is too strict if (policy.can_add(int(tellp()), *it)) { MYSQLPP_QUERY_THISPTR << std::setprecision(16) << "INSERT INTO `" << it->table() << "` (" << it->field_list() << ") VALUES (" << it->value_list() << ')'; empty = false; } else { // At this point all we can do is give up if (throw_exceptions()) { throw BadInsertPolicy("Insert policy is too strict"); } success = false; break; } } } // We might need to execute the last query here. if (success && !empty && !exec()) { success = false; } if (success) { ac.commit(); } else { ac.rollback(); } return *this; } /// \brief Replace multiple new rows using an insert policy to /// control how the REPLACE statements are created using /// items from an STL container. /// /// \param first iterator pointing to first element in range to /// replace /// \param last iterator pointing to one past the last element to /// replace /// \param policy insert policy object, see insertpolicy.h for /// details /// /// \sa insert() template <class Iter, class InsertPolicy> Query& replacefrom(Iter first, Iter last, InsertPolicy& policy) { bool success = true; bool empty = true; reset(); if (first == last) { return *this; // empty set! } typename InsertPolicy::access_controller ac(*conn_); for (Iter it = first; it != last; ++it) { if (policy.can_add(int(tellp()), *it)) { if (empty) { MYSQLPP_QUERY_THISPTR << std::setprecision(16) << "REPLACE INTO `" << it->table() << "` (" << it->field_list() << ") VALUES ("; } else { MYSQLPP_QUERY_THISPTR << ",("; } MYSQLPP_QUERY_THISPTR << it->value_list() << ')'; empty = false; } else { // Execute what we've built up already, if there is anything if (!empty) { if (!exec()) { success = false; break; } empty = true; } // If we _still_ can't add, the policy is too strict if (policy.can_add(int(tellp()), *it)) { MYSQLPP_QUERY_THISPTR << std::setprecision(16) << "REPLACE INTO `" << it->table() << "` (" << it->field_list() << ") VALUES (" << it->value_list() << ')'; empty = false; } else { // At this point all we can do is give up if (throw_exceptions()) { throw BadInsertPolicy("Insert policy is too strict"); } success = false; break; } } } // We might need to execute the last query here. if (success && !empty && !exec()) { success = false; } if (success) { ac.commit(); } else { ac.rollback(); } 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 Insert multiple new rows, or replace existing ones if /// there are existing rows that match on key fields. /// /// Builds a REPLACE 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/replace /// \param last iterator pointing to one past the last element to /// insert/replace /// /// \sa insertfrom(), replace(), update() template <class Iter> Query& replace(Iter first, Iter last) { reset(); if (first != last) { // Build SQL for first item in the container. It's special // because we need the table name and field list. MYSQLPP_QUERY_THISPTR << std::setprecision(16) << "REPLACE INTO " << first->table() << " (" << first->field_list() << ") VALUES (" << first->value_list() << ')'; // Now insert any remaining container elements. Be careful // hacking on the iterator use here: we want it to work // with containers providing only a forward iterator. Iter it = first; while (++it != last) { MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')'; } } return *this; } #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, str) mysql_query_define0(SimpleResult, execute) mysql_query_define0(StoreQueryResult, store) mysql_query_define0(UseQueryResult, use) mysql_query_define1(storein_sequence) mysql_query_define1(storein_set) mysql_query_define1(storein) #endif // !defined(DOXYGEN_IGNORE) /// \brief The default template parameters /// /// Used for filling in parameterized queries. SQLQueryParms template_defaults; private: friend class SQLQueryParms; /// \brief Connection to send queries through Connection* conn_; /// \brief If true, last query succeeded bool copacetic_; /// \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_; /// \brief Process a parameterized query list. void proc(SQLQueryParms& p); SQLTypeAdapter* pprepare(char option, SQLTypeAdapter& S, bool replace = true); }; /// \brief Insert raw query string into the given stream. /// /// This is just syntactic sugar for Query::str(void) inline std::ostream& operator <<(std::ostream& os, Query& q) { return os << q.str(); } } // end namespace mysqlpp #endif // !defined(MYSQLPP_QUERY_H) |
Added 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 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // 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 MYSQLPP_TQUERY_MAX_PARAMETERS 25 #define mysql_query_define0(RETURN, FUNC) \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1) \ { return FUNC(SQLQueryParms() << arg0 << arg1); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16) \ { return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16); } \ RETURN FUNC(const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& arg21, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& arg21, const SQLTypeAdapter& arg22, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& arg21, const SQLTypeAdapter& arg22, const SQLTypeAdapter& arg23, const SQLTypeAdapter& 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(FUNC) \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1) \ { FUNC(container, SQLQueryParms() << arg0 << arg1); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11) \ { FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11); } \ template <class T> void FUNC(T& container, const SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& arg21, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& arg21, const SQLTypeAdapter& arg22, const SQLTypeAdapter& 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 SQLTypeAdapter& arg0, const SQLTypeAdapter& arg1, const SQLTypeAdapter& arg2, const SQLTypeAdapter& arg3, const SQLTypeAdapter& arg4, const SQLTypeAdapter& arg5, const SQLTypeAdapter& arg6, const SQLTypeAdapter& arg7, const SQLTypeAdapter& arg8, const SQLTypeAdapter& arg9, const SQLTypeAdapter& arg10, const SQLTypeAdapter& arg11, const SQLTypeAdapter& arg12, const SQLTypeAdapter& arg13, const SQLTypeAdapter& arg14, const SQLTypeAdapter& arg15, const SQLTypeAdapter& arg16, const SQLTypeAdapter& arg17, const SQLTypeAdapter& arg18, const SQLTypeAdapter& arg19, const SQLTypeAdapter& arg20, const SQLTypeAdapter& arg21, const SQLTypeAdapter& arg22, const SQLTypeAdapter& arg23, const SQLTypeAdapter& 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) |
Added 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 | #!/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-2010 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; use Getopt::Std; our $opt_f; getopts('f:') or die "usage: $0 [-f fields]\n\n"; $max_parameters = int($opt_f) if defined $opt_f; 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 #define MYSQLPP_TQUERY_MAX_PARAMETERS $max_parameters --- ## 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 SQLTypeAdapter& 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"; } print OUT "\n"; ## Add mysql_query_define1 macro print OUT "#define mysql_query_define1(FUNC) \\\n"; for (my $i = 1; $i < $max_parameters; ++$i) { print OUT "\ttemplate <class T> void FUNC(T& container"; for (my $j = 0; $j < $i + 1; ++$j) { print OUT ', const SQLTypeAdapter& 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"; } print OUT "\n"; ## That's all, folks! print OUT "#endif // !defined(MYSQLPP_QUERYDEF_H)\n"; |
Added lib/refcounted.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 | /// \file refcounted.h /// \brief Declares the RefCountedPointer template /*********************************************************************** Copyright (c) 2007-2011 by Educational Technology Resources, Inc. and (c) 2007 by Jonathan Wakely. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_REFCOUNTED_H) #define MYSQLPP_REFCOUNTED_H #include <memory> #include <stddef.h> namespace mysqlpp { /// \brief Functor to call delete on the pointer you pass to it /// /// The default "destroyer" for RefCountedPointer. You won't use this /// directly, you'll pass a functor of your own devising for the second /// parameter to the RefCountedPointer template to override this. Or /// simpler, just specialize this template for your type if possible: /// see ResUse::result_. template <class T> struct RefCountedPointerDestroyer { /// \brief Functor implementation void operator()(T* doomed) const { delete doomed; } }; /// \brief Creates an object that acts as a reference-counted pointer /// to another object. /// /// Resulting type acts like a pointer in all respects, except that it /// manages the memory it points to by observing how many users there /// are for the object. /// /// This attempts to be as automatic as reference counting in a /// programming language with memory management. Like all automatic /// memory management schemes, it has penalties: it turns the single /// indirection of an unmanaged pointer into a double indirection, and /// has additional management overhead in the assignment operators due /// to the reference counter. This is an acceptable tradeoff when /// wrapping objects that are expensive to copy, and which need to /// be "owned" by disparate parties: you can allocate the object just /// once, then pass around the reference counted pointer, knowing that /// the last user will "turn out the lights". /// /// \b Implementation \b detail: You may notice that this class manages /// two pointers, one to the data we're managing, and one to the /// reference count. You might wonder why we don't wrap these up into a /// structure and keep just a pointer to an instance of it to simplify /// the memory management. It would indeed do that, but then every /// access to the data we manage would be a triple indirection instead /// of just double. It's a tradeoff, and we've chosen to take a minor /// complexity hit to avoid the performance hit. template <class T, class Destroyer = RefCountedPointerDestroyer<T> > class RefCountedPointer { public: typedef RefCountedPointer<T> ThisType; ///< alias for this object's type /// \brief Default constructor /// /// An object constructed this way is useless until you vivify it /// with operator =() or assign(). RefCountedPointer() : counted_(0), refs_(0) { } /// \brief Standard constructor /// /// \param c A pointer to the object to be managed. If you pass 0, /// it's like calling the default ctor instead, only more work: the /// object's useless until you vivify it with operator =() or assign(). explicit RefCountedPointer(T* c) : counted_(c), refs_(0) { std::auto_ptr<T> exception_guard(counted_); if (counted_) { refs_ = new size_t(1); } exception_guard.release(); // previous new didn't throw } /// \brief Copy constructor RefCountedPointer(const ThisType& other) : counted_(other.counted_), refs_(other.counted_ ? other.refs_ : 0) { if (counted_) { ++(*refs_); } } /// \brief Destructor /// /// This only destroys the managed memory if the reference count /// drops to 0. ~RefCountedPointer() { if (refs_ && (--(*refs_) == 0)) { Destroyer()(counted_); delete refs_; } } /// \brief Sets (or resets) the pointer to the counted object. /// /// If we are managing a pointer, this decrements the refcount for /// it and destroys the managed object if the refcount falls to 0. /// /// This is a no-op if you pass the same pointer we're already /// managing. ThisType& assign(T* c) { // The create-temporary-and-swap idiom lets us keep memory // allocation in the ctor and deallocation in the dtor so // we don't leak in the face of an exception. ThisType(c).swap(*this); return *this; } /// \brief Copy an existing refcounted pointer /// /// If we are managing a pointer, this decrements the refcount for /// it and destroys the managed object if the refcount falls to 0. /// Then we increment the other object's reference count and copy /// that refcount and the managed pointer into this object. /// /// This is a no-op if you pass a reference to this same object. ThisType& assign(const ThisType& other) { // The create-temporary-and-swap idiom lets us keep memory // allocation in the ctor and deallocation in the dtor so // we don't leak in the face of an exception. ThisType(other).swap(*this); return *this; } /// \brief Set (or reset) the pointer to the counted object /// /// This is essentially the same thing as assign(T*). The choice /// between the two is just a matter of syntactic preference. ThisType& operator =(T* c) { return assign(c); } /// \brief Copy an existing refcounted pointer /// /// This is essentially the same thing as assign(const ThisType&). /// The choice between the two is just a matter of syntactic /// preference. ThisType& operator =(const ThisType& rhs) { return assign(rhs); } /// \brief Access the object through the smart pointer T* operator ->() const { return counted_; } /// \brief Dereference the smart pointer T& operator *() const { return *counted_; } /// \brief Returns the internal raw pointer converted to void* /// /// This isn't intended to be used directly; if you need the /// pointer, call raw() instead. It's used internally by the /// compiler to implement operators bool, ==, and != /// /// \b WARNING: This makes it possible to say /// \code /// RefCountedPointer<Foo> bar(new Foo); /// delete bar; /// \endcode /// /// This will almost kinda sorta do the right thing: the Foo /// object held by the refcounted pointer will be destroyed as /// you wanted, but then when the refcounted pointer goes out of /// scope, the memory is deleted a second time, which will probably /// crash your program. This is easy to accidentally do when /// converting a good ol' unmanaged pointer to a refcounted pointer /// and forgetting to remove the delete calls needed previously. operator void*() { return counted_; } /// \brief Returns the internal raw pointer converted to const void* /// /// \see comments for operator void*() operator const void*() const { return counted_; } /// \brief Return the raw pointer in T* context T* raw() { return counted_; } /// \brief Return the raw pointer when used in const T* context const T* raw() const { return counted_; } /// \brief Exchange our managed memory with another pointer. /// /// \internal This exists primarily to implement assign() in an /// exception-safe manner. void swap(ThisType& other) { std::swap(counted_, other.counted_); std::swap(refs_, other.refs_); } private: /// \brief Pointer to the reference-counted object T* counted_; /// \brief Pointer to the reference count. /// /// We can't keep this as a plain integer because this object /// allows itself to be copied. All copies need to share this /// reference count, not just the pointer to the counted object. size_t* refs_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_REFCOUNTED_H) |
Deleted lib/resiter.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to lib/result.cpp.
1 | /*********************************************************************** | | > | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /*********************************************************************** result.cpp - Implements the ResultBase, StoreQueryResult and UseQuery Result classes. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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. |
︙ | ︙ | |||
22 23 24 25 26 27 28 | 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" | | > | | | | | > > > > > > | > > > | > | | > | > > > | > > > | | > > > > | < < | | | > > > | | | | > > > | > > | | | > > > | > > > | > > | > > > > > > > | > > | | > > | > > > > | | > > | | > > > > > > > | | > > | > > | | > | | > > | | | | > | > > > | > > > | < > > | | < > | | | < > > > > > | | > > > | > | | < | > > > > > > > > | | > > > > > | 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 | 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 "dbdriver.h" namespace mysqlpp { ResultBase::ResultBase(MYSQL_RES* res, DBDriver* dbd, bool te) : OptionalExceptions(te), driver_(res ? dbd : 0), fields_(Fields::size_type(res ? dbd->num_fields(res) : 0)), current_field_(0) { if (res) { Fields::size_type i = 0; const MYSQL_FIELD* pf; while ((i < fields_.size()) && (pf = dbd->fetch_field(res))) { fields_[i++] = pf; } dbd->field_seek(res, 0); // semantics break otherwise! names_ = new FieldNames(this); types_ = new FieldTypes(this); } } ResultBase& ResultBase::copy(const ResultBase& other) { if (this != &other) { set_exceptions(other.throw_exceptions()); if (other.driver_) { driver_ = other.driver_; fields_ = other.fields_; names_ = other.names_; types_ = other.types_; current_field_ = other.current_field_; } else { driver_ = 0; fields_.clear(); names_ = 0; types_ = 0; current_field_ = 0; } } return *this; } int ResultBase::field_num(const std::string& i) const { size_t index = (*names_)[i]; if ((index >= names_->size()) && throw_exceptions()) { if (throw_exceptions()) { throw BadFieldName(i.c_str()); } else { return -1; } } return int(index); } StoreQueryResult::StoreQueryResult(MYSQL_RES* res, DBDriver* dbd, bool te) : ResultBase(res, dbd, te), list_type(list_type::size_type(res && dbd ? dbd->num_rows(res) : 0)), copacetic_(res && dbd) { if (copacetic_) { iterator it = begin(); while (MYSQL_ROW row = dbd->fetch_row(res)) { if (const unsigned long* lengths = dbd->fetch_lengths(res)) { *it = Row(row, this, lengths, throw_exceptions()); ++it; } } dbd->free_result(res); } } StoreQueryResult& StoreQueryResult::copy(const StoreQueryResult& other) { if (this != &other) { ResultBase::copy(other); assign(other.begin(), other.end()); copacetic_ = other.copacetic_; } return *this; } UseQueryResult::UseQueryResult(MYSQL_RES* res, DBDriver* dbd, bool te) : ResultBase(res, dbd, te) { if (res) { result_ = res; } } UseQueryResult& UseQueryResult::copy(const UseQueryResult& other) { if (this != &other) { ResultBase::copy(other); if (other.result_) { result_ = other.result_; } else { result_ = 0; } } return *this; } const unsigned long* UseQueryResult::fetch_lengths() const { return driver_->fetch_lengths(result_.raw()); } Row UseQueryResult::fetch_row() const { if (!result_) { if (throw_exceptions()) { throw UseQueryError("Results not fetched"); } else { return Row(); } } MYSQL_ROW row = driver_->fetch_row(result_.raw()); if (row) { const unsigned long* lengths = fetch_lengths(); if (lengths) { return Row(row, this, lengths, throw_exceptions()); } else { if (throw_exceptions()) { throw UseQueryError("Failed to get field lengths"); } else { return Row(); } } } else { // Prior to v3, this was considered an error, but it just means // we've fallen off the end of a "use" query's result set. You // can't predict when this will happen, but it isn't an error. // Just return a falsy row object so caller's loop terminates. return Row(); } } MYSQL_ROW UseQueryResult::fetch_raw_row() const { return driver_->fetch_row(result_.raw()); } } // end namespace mysqlpp |
Changes to lib/result.h.
1 | /// \file 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 | /// \file result.h /// \brief Declares classes for holding information about SQL query /// results. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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_RESULT_H) #define MYSQLPP_RESULT_H #include "common.h" #include "exceptions.h" #include "field.h" #include "field_names.h" #include "field_types.h" #include "noexceptions.h" #include "refcounted.h" #include "row.h" namespace mysqlpp { /// \brief Holds information about the result of queries that don't /// return rows. class MYSQLPP_EXPORT SimpleResult { private: /// \brief Pointer to bool data member, for use by safe bool /// conversion operator. /// /// \see http://www.artima.com/cppsource/safebool.html typedef bool SimpleResult::*private_bool_type; public: /// \brief Default ctor SimpleResult() : copacetic_(false), insert_id_(0), rows_(0) { } /// \brief Initialize object SimpleResult(bool copacetic, ulonglong insert_id, ulonglong rows, const std::string& info) : copacetic_(copacetic), insert_id_(insert_id), rows_(rows), info_(info) { } /// \brief Test whether the query that created this result succeeded /// /// If you test this object in bool context and it's false, it's a /// signal that the query this was created from failed in some way. /// Call Query::error() or Query::errnum() to find out what exactly /// happened. operator private_bool_type() const { return copacetic_ ? &SimpleResult::copacetic_ : 0; } /// \brief Get the last value used for an AUTO_INCREMENT field ulonglong insert_id() const { return insert_id_; } /// \brief Get the number of rows affected by the query ulonglong rows() const { return rows_; } /// \brief Get any additional information about the query returned /// by the server. const char* info() const { return info_.c_str(); } private: bool copacetic_; ulonglong insert_id_; ulonglong rows_; std::string info_; }; /// \brief Base class for StoreQueryResult and UseQueryResult. /// /// Not useful directly. Just contains common functionality for its /// subclasses. class MYSQLPP_EXPORT ResultBase : public OptionalExceptions { public: /// \brief Destroy object virtual ~ResultBase() { } /// \brief Returns the next field in this result set const Field& fetch_field() const { return fields_.at(current_field_++); } /// \brief Returns the given field in this result set const Field& fetch_field(Fields::size_type i) const { return fields_.at(i); } /// \brief Get the underlying Field structure given its index. const Field& field(unsigned int i) const { return fields_.at(i); } /// \brief Get the underlying Fields structure. const Fields& fields() const { return fields_; } /// \brief Get the name of the field at the given index. const std::string& field_name(int i) const { return names_->at(i); } /// \brief Get the names of the fields within this result set. const RefCountedPointer<FieldNames>& field_names() const { return names_; } /// \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 type of a particular field within this result set. const FieldTypes::value_type& field_type(int i) const { return types_->at(i); } /// \brief Get a list of the types of the fields within this /// result set. const RefCountedPointer<FieldTypes>& field_types() const { return types_; } /// \brief Returns the number of fields in this result set size_t num_fields() const { return fields_.size(); } /// \brief Return the name of the table the result set comes from const char* table() const { return fields_.empty() ? "" : fields_[0].table(); } protected: /// \brief Create empty object ResultBase() : driver_(0), current_field_(0) { } /// \brief Create the object, fully initialized ResultBase(MYSQL_RES* result, DBDriver* dbd, bool te = true); /// \brief Create object as a copy of another ResultBase ResultBase(const ResultBase& other) : OptionalExceptions() { copy(other); } /// \brief Copy another ResultBase object's contents into this one. ResultBase& copy(const ResultBase& other); DBDriver* driver_; ///< Access to DB driver; fully initted if nonzero Fields fields_; ///< list of fields in result /// \brief list of field names in result RefCountedPointer<FieldNames> names_; /// \brief list of field types in result RefCountedPointer<FieldTypes> types_; /// \brief Default field index used by fetch_field() /// /// It's mutable because it's just internal housekeeping: it's /// changed by fetch_field(void), but it doesn't change the "value" /// of the result. See mutability justification for /// UseQueryResult::result_: this field provides functionality we /// used to get through result_, so it's relevant here, too. mutable Fields::size_type current_field_; }; /// \brief StoreQueryResult set type for "store" queries /// /// This is the obvious C++ implementation of a class to hold results /// from a SQL query that returns rows: a specialization of std::vector /// holding Row objects in memory so you get random-access semantics. /// MySQL++ also supports UseQueryResult which is less friendly, but has /// better memory performance. See the user manual for more details on /// the distinction and the usage patterns required. class MYSQLPP_EXPORT StoreQueryResult : public ResultBase, public std::vector<Row> { private: /// \brief Pointer to bool data member, for use by safe bool /// conversion operator. /// /// \see http://www.artima.com/cppsource/safebool.html typedef bool StoreQueryResult::*private_bool_type; public: typedef std::vector<Row> list_type; ///< type of vector base class /// \brief Default constructor StoreQueryResult() : ResultBase(), copacetic_(false) { } /// \brief Fully initialize object StoreQueryResult(MYSQL_RES* result, DBDriver* dbd, bool te = true); /// \brief Initialize object as a copy of another StoreQueryResult /// object StoreQueryResult(const StoreQueryResult& other) : ResultBase(), std::vector<Row>(), copacetic_(false) { copy(other); } /// \brief Destroy result set ~StoreQueryResult() { } /// \brief Returns the number of rows in this result set list_type::size_type num_rows() const { return size(); } /// \brief Copy another StoreQueryResult object's data into this /// object StoreQueryResult& operator =(const StoreQueryResult& rhs) { return this != &rhs ? copy(rhs) : *this; } /// \brief Test whether the query that created this result succeeded /// /// If you test this object in bool context and it's false, it's a /// signal that the query this was created from failed in some way. /// Call Query::error() or Query::errnum() to find out what exactly /// happened. operator private_bool_type() const { return copacetic_ ? &StoreQueryResult::copacetic_ : 0; } private: /// \brief Copy another StoreQueryResult object's contents into this /// one. StoreQueryResult& copy(const StoreQueryResult& other); bool copacetic_; ///< true if initialized from a good result set }; /// \brief Functor to call mysql_free_result() on the pointer you pass /// to it. /// /// This overrides RefCountedPointer's default destroyer, which uses /// operator delete; it annoys the C API when you nuke its data /// structures this way. :) template <> struct RefCountedPointerDestroyer<MYSQL_RES> { /// \brief Functor implementation void operator()(MYSQL_RES* doomed) const { if (doomed) { mysql_free_result(doomed); } } }; /// \brief StoreQueryResult set type for "use" queries /// /// See the user manual for the reason you might want to use this even /// though its interface is less friendly than StoreQueryResult's. class MYSQLPP_EXPORT UseQueryResult : public ResultBase { public: /// \brief Default constructor UseQueryResult() : ResultBase() { } /// \brief Create the object, fully initialized UseQueryResult(MYSQL_RES* result, DBDriver* dbd, bool te = true); /// \brief Create a copy of another UseQueryResult object UseQueryResult(const UseQueryResult& other) : ResultBase() { copy(other); } /// \brief Destroy object ~UseQueryResult() { } /// \brief Copy another UseQueryResult object's data into this object UseQueryResult& operator =(const UseQueryResult& rhs) { return this != &rhs ? copy(rhs) : *this; } /// \brief Returns the next field in this result set const Field& fetch_field() const { return fields_.at(current_field_++); } /// \brief Returns the given field in this result set const Field& fetch_field(Fields::size_type i) const { return fields_.at(i); } /// \brief Returns the lengths of the fields in the current row of /// the result set. /// /// \internal This should not be terribly useful to end-user code. /// The Row object returned by fetch_row() contains these lengths. const unsigned long* fetch_lengths() const; /// \brief Returns the next row in a "use" query's result set /// /// This is a thick wrapper around DBDriver::fetch_row(). It does a /// lot of error checking before returning the Row object containing /// the row data. /// /// \sa fetch_raw_row() Row fetch_row() const; /// \brief Wraps mysql_fetch_row() in MySQL C API. /// /// \internal You almost certainly want to call fetch_row() instead. /// It is anticipated that this is only useful within the library, /// to implement higher-level query types on top of raw "use" /// queries. Query::storein() uses it, for example. MYSQL_ROW fetch_raw_row() const; /// \brief Jumps to the given field within the result set /// /// Calling this allows you to reset the default field index used /// by fetch_field(). void field_seek(Fields::size_type field) const { current_field_ = field; } /// \brief Return the pointer to the underlying MySQL C API /// result set object. /// /// While this has obvious inherent value for those times you need /// to dig beneath the MySQL++ interface, it has subtler value. /// It effectively stands in for operator bool(), operator !(), /// operator ==(), and operator !=(), because the C++ compiler can /// implement all of these with a MYSQL_RES*. /// /// Of these uses, the most valuable is using the UseQueryResult /// object in bool context to determine if the query that created // it was successful: /// /// \code /// Query q("...."); /// if (UseQueryResult res = q.use()) { /// // Can use 'res', query succeeded /// } /// else { /// // Query failed, call Query::error() or ::errnum() for why /// } /// \endcode operator MYSQL_RES*() const { return result_.raw(); } private: /// \brief Copy another ResultBase object's contents into this one. UseQueryResult& copy(const UseQueryResult& other); /// \brief Reference to underlying C API result set /// /// This is mutable because so many methods in this class are /// are justifiably const because they don't modify the result /// set's "value" but they call C API methods that take non-const /// MYSQL_RES* so they can only be const if this is mutable. It's /// quite likely that these API functions do modify the MYSQL_RES /// object, so strict constness says this object changed, too, but /// this has always been mutable and the resulting behavior hasn't /// confused anyone yet. mutable RefCountedPointer<MYSQL_RES> result_; }; /// \brief Swaps two StoreQueryResult objects inline void swap(StoreQueryResult& x, StoreQueryResult& y) { StoreQueryResult tmp = x; x = y; y = tmp; } /// \brief Swaps two UseQueryResult objects inline void swap(UseQueryResult& x, UseQueryResult& y) { UseQueryResult tmp = x; x = y; y = tmp; } } // end namespace mysqlpp #endif // !defined(MYSQLPP_RESULT_H) |
Changes to lib/row.cpp.
1 2 3 | /*********************************************************************** row.cpp - Implements the Row class. | | | | | > | | | | < | | > > > > > | < > | | | | | < | < < < < | > > | | > > | < < < < < < < < < | | | | | < < < | > > < < | > | | < | > > > > > > | > | > | > | > | > | | > | | > | | | > | > > > > > > > | < | | | | > | > > > > > > > > > | < | > > | 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 | /*********************************************************************** row.cpp - Implements the Row class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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" namespace mysqlpp { Row::Row(MYSQL_ROW row, const ResultBase* res, const unsigned long* lengths, bool throw_exceptions) : OptionalExceptions(throw_exceptions), initialized_(false) { if (row) { if (res) { size_type size = res->num_fields(); data_.reserve(size); for (size_type i = 0; i < size; ++i) { bool is_null = row[i] == 0; data_.push_back(value_type( is_null ? "NULL" : row[i], is_null ? 4 : lengths[i], res->field_type(int(i)), is_null)); } field_names_ = res->field_names(); initialized_ = true; } else if (throw_exceptions) { throw ObjectNotInitialized("RES is NULL"); } } else if (throw_exceptions) { throw ObjectNotInitialized("ROW is NULL"); } } Row::const_reference Row::at(size_type i) const { if (i < size()) { return data_[i]; } else { throw BadIndex("Row", int(i), int(size())); } } 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>( *field_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>( *field_names_, *this, d, e, m); } value_list_ba<FieldNames, do_nothing_type0> Row::field_list(const char* d) const { return value_list_ba<FieldNames, do_nothing_type0> (*field_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>(*field_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>(*field_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>(*field_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>(*field_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(field_names_->size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc); return value_list_b<FieldNames, Manip>(*field_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(field_names_->size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc); return value_list_b<FieldNames, quote_type0>(*field_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(field_names_->size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc); return value_list_b<FieldNames, quote_type0>(*field_names_, vb, ",", quote); } Row::size_type Row::field_num(const char* name) const { if (field_names_) { return (*field_names_)[name]; } else if (throw_exceptions()) { throw BadFieldName(name); } else { return 0; } } const Row::value_type& Row::operator [](const char* field) const { size_type si = field_num(field); if (si < size()) { return at(si); } else if (throw_exceptions()) { throw BadFieldName(field); } else { static value_type empty; return empty; } } } // end namespace mysqlpp |
Changes to lib/row.h.
1 2 3 4 | /// \file row.h /// \brief Declares the classes for holding row data from a result set. /*********************************************************************** | | | | | | | > | | < < > > | > > | > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > > > > > > > > | | | | | | > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > | > < | < < | | > | < < < < < < | | < | | < < < < < < > | | | < < < | > | < < < < | < < < | | | < > > > > > | | < < | < < < < | | | | > | > > | | > > | 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 row.h /// \brief Declares the classes for holding row data from a result set. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_ROW_H) #define MYSQLPP_ROW_H #include "common.h" #include "mystring.h" #include "noexceptions.h" #include "refcounted.h" #include "vallist.h" #include <vector> #include <string> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class FieldNames; class MYSQLPP_EXPORT ResultBase; #endif /// \brief Manages rows from a result set. /// /// This class is like an extended version of a \c const \c std::vector /// of mysqlpp::String. It adds stuff for populating the vector. As /// for why it's \c const, what would it mean to modify a Row? If we /// ever did support such semantics, it should probably actually modify /// the database. We can't do that if we just derive from std::vector. /// /// Not that we could derive from std::vector even if we wanted to: /// \c vector::operator[](size_type) would interfere with our /// \c operator[](const \c char*). We can avoid this only by /// maintaining our own public inteface independent of that of /// \c vector. class MYSQLPP_EXPORT Row : public OptionalExceptions { private: /// \brief Pointer to bool data member, for use by safe bool /// conversion operator. /// /// \see http://www.artima.com/cppsource/safebool.html typedef bool Row::*private_bool_type; public: /// \brief type of our internal data list /// /// This is public because all other typedefs we have for /// mirroring std::vector's public interface depend on it. typedef std::vector<String> list_type; /// \brief constant iterator type typedef list_type::const_iterator const_iterator; /// \brief constant reference type typedef list_type::const_reference const_reference; /// \brief const reverse iterator type typedef list_type::const_reverse_iterator const_reverse_iterator; /// \brief type for index differences typedef list_type::difference_type difference_type; /// \brief iterator type /// /// Note that this is just an alias for the const iterator. Row /// is immutable, but people are in the habit of saying 'iterator' /// even when they don't intend to use the iterator to modify the /// container, so we provide this as a convenience. typedef const_iterator iterator; /// \brief reference type /// /// \sa iterator for justification for this const_reference alias typedef const_reference reference; /// \brief mutable reverse iterator type /// /// \sa iterator for justification for this const_reverse_iterator /// alias typedef const_reverse_iterator reverse_iterator; /// \brief type of returned sizes typedef list_type::size_type size_type; /// \brief type of data in container typedef list_type::value_type value_type; /// \brief Default constructor Row() : initialized_(false) { } /// \brief Copy constructor Row(const Row& r) : OptionalExceptions(), data_(r.data_.begin(), r.data_.end()), field_names_(r.field_names_), initialized_(r.initialized_) { } /// \brief Create a row object /// /// \param row MySQL C API row data /// \param res result set that the row comes from /// \param lengths length of each item in row /// \param te if true, throw exceptions on errors Row(MYSQL_ROW row, const ResultBase* res, const unsigned long* lengths, bool te = true); /// \brief Destroy object ~Row() { } /// \brief Get a const reference to the field given its index /// /// \throw mysqlpp::BadIndex if the row is not initialized or there /// are less than \c i fields in the row. const_reference at(size_type i) const; /// \brief Get a reference to the last element of the vector const_reference back() const { return data_.back(); } /// \brief Return a const iterator pointing to first element in the /// container const_iterator begin() const { return data_.begin(); } /// \brief Returns true if container is empty bool empty() const { return data_.empty(); } /// \brief Return a const iterator pointing to one past the last /// element in the container const_iterator end() const { return data_.end(); } /// \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; /// \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 Returns a field's index given its name size_type field_num(const char* name) const; /// \brief Get a reference to the first element of the vector const_reference front() const { return data_.front(); } /// \brief Return maximum number of elements that can be stored /// in container without resizing. size_type max_size() const { return data_.max_size(); } /// \brief Assignment operator Row& operator =(const Row& rhs) { data_.assign(rhs.data_.begin(), rhs.data_.end()); field_names_.assign(rhs.field_names_); initialized_ = rhs.initialized_; return *this; } /// \brief Get the value of a field given its name. /// /// If the field does not exist in this row, we throw a BadFieldName /// exception if exceptions are enabled, or an empty row if not. /// An empty row tests as false in bool context. /// /// This operator is fairly inefficient. operator[](int) is faster. const_reference 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. /// /// It's \b critical that the parameter type be \c int, not /// \c size_type, because it will interfere with the \c const /// \c char* overload otherwise. row[0] is ambiguous when there /// isn't an int overload. /// /// \throw mysqlpp::BadIndex if the row is not initialized or there /// are less than \c i fields in the row. const_reference operator [](int i) const { return at(static_cast<size_type>(i)); } /// \brief Returns true if row object was fully initialized and /// has data. /// /// This operator lets you use Row in bool context, which lets you /// do things like tell when you've run off the end of a "use" /// query's result set: /// /// \code /// Query q("...."); /// if (UseQueryResult res = q.use()) { /// // Can use 'res', query succeeded /// while (Row row = res.fetch_row()) { /// // Retreived another row in the result set, can use 'row' /// } /// } /// \endcode /// operator private_bool_type() const { return data_.size() && initialized_ ? &Row::initialized_ : 0; } /// \brief Return reverse iterator pointing to first element in the /// container const_reverse_iterator rbegin() const { return data_.rbegin(); } /// \brief Return reverse iterator pointing to one past the last /// element in the container const_reverse_iterator rend() const { return data_.rend(); } /// \brief Get the number of fields in the row. size_type size() 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. /// |
︙ | ︙ | |||
309 310 311 312 313 314 315 | { 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); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < > | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | { 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); } private: list_type data_; RefCountedPointer<FieldNames> field_names_; bool initialized_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_ROW_H) |
Added lib/scopedconnection.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 | /*********************************************************************** scopedconnection.cpp - Implements the ScopedConnection class. Copyright (c) 2010 by Switchplane, Ltd. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "scopedconnection.h" #include "cpool.h" namespace mysqlpp { ScopedConnection::ScopedConnection(ConnectionPool& pool, bool safe) : pool_(pool), connection_(safe ? pool.safe_grab() : pool.grab()) { } ScopedConnection::~ScopedConnection() { pool_.release(connection_); } } // end namespace mysqlpp |
Added lib/scopedconnection.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 | /// \file scopedconnection.h /// \brief Declares the ScopedConnection class. /// /// This class lets you grab a connection from a ConnectionPool in a /// scoped and therefore RAII way. The Connection object will always be /// returned to the pool when the scope block ends, plugging a potential /// leak in the pool. /*********************************************************************** Copyright (c) 2010 by Joel Fielder. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_SCOPEDCONNECTION_H) #define MYSQLPP_SCOPEDCONNECTION_H #include "common.h" namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT Connection; class MYSQLPP_EXPORT ConnectionPool; #endif /// \brief Grabs a Connection from a ConnectionPool on construction /// and releases it back to the pool on destruction, and provides access /// to the relevant Connection pointer. class MYSQLPP_EXPORT ScopedConnection { public: /// \brief Standard constructor /// /// Grabs a Connection from the specified pool. /// /// \internal Note that there is no default ctor on purpose. RAII. /// /// \param pool The ConnectionPool to use. /// \param safe By default, we get the connection from the pool with /// ConnectionPool::grab(), but we can call safe_grab() instead. explicit ScopedConnection(ConnectionPool& pool, bool safe = false); /// \brief Destructor /// /// Releases the Connection back to the ConnectionPool. ~ScopedConnection(); /// \brief Access the Connection pointer Connection* operator->() const { return connection_; } /// \brief Dereference Connection& operator*() const { return *connection_; } /// \brief Truthiness operator operator void*() const { return connection_; } private: // ScopedConnection objects cannot be copied. We want them to be // tightly scoped to their use point, not put in containers or // passed around promiscuously. ScopedConnection(const ScopedConnection& no_copies); const ScopedConnection& operator=(const ScopedConnection& no_copies); ConnectionPool& pool_; Connection* const connection_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_SCOPEDCONNECTION_H) |
Added lib/sql_buffer.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 | /*********************************************************************** sql_buffer.cpp - Implements the SQLBuffer class. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_buffer.h" #include "datetime.h" #include "sql_types.h" #include <string.h> namespace mysqlpp { SQLBuffer& SQLBuffer::assign(const char* data, size_type length, mysql_type_info type, bool is_null) { replace_buffer(data, length); type_ = type; is_null_ = is_null; return *this; } SQLBuffer& SQLBuffer::assign(const std::string& s, mysql_type_info type, bool is_null) { replace_buffer(s.data(), s.length()); type_ = type; is_null_ = is_null; return *this; } bool SQLBuffer::quote_q() const { if ((type_.base_type().c_type() == typeid(mysqlpp::sql_datetime)) && data_ && (length_ >= 5) && (memcmp(data_, "NOW()", 5) == 0)) { // The default DATETIME value is special-cased as a call to the // SQL NOW() function, which must not be quoted. return false; } else { // Normal case: we can infer the need to quote from the type. return type_.quote_q(); } } void SQLBuffer::replace_buffer(const char* pd, size_type length) { delete[] data_; data_ = 0; length_ = 0; if (pd) { // The casts for the data member are because the C type system // can't distinguish initialization from modification when it // happens in 2 steps like this. // // We cast away const for pd in case we're on a system that uses // the old definition of memcpy() with non-const 2nd parameter. data_ = new char[length + 1]; length_ = length; memcpy(const_cast<char*>(data_), const_cast<char*>(pd), length_); const_cast<char*>(data_)[length_] = '\0'; } } } // end namespace mysqlpp |
Added lib/sql_buffer.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 | /// \file sql_buffer.h /// \brief Declares the SQLBuffer class /*********************************************************************** Copyright (c) 2007-2008 by Educational Technology Resources, Inc. and (c) 2007 by Jonathan Wakely. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_BUFFER_H) #define MYSQLPP_SQL_BUFFER_H #include "refcounted.h" #include "type_info.h" #include <string> namespace mysqlpp { /// \brief Holds SQL data in string form plus type information for use /// in converting the string to compatible C++ data types. class SQLBuffer { public: /// \brief Type of length values typedef size_t size_type; /// \brief Initialize object as a copy of a raw data buffer /// /// Copies the string into a new buffer one byte longer than /// the length value given, using that to hold a C string null /// terminator, just for safety. The length value we keep does /// not include this extra byte, allowing this same mechanism /// to work for both C strings and binary data. SQLBuffer(const char* data, size_type length, mysql_type_info type, bool is_null) : data_(), length_(), type_(type), is_null_(is_null) { replace_buffer(data, length); } /// \brief Initialize object as a copy of a C++ string object SQLBuffer(const std::string& s, mysql_type_info type, bool is_null) : data_(), length_(), type_(type), is_null_(is_null) { replace_buffer(s.data(), static_cast<size_type>(s.length())); } /// \brief Destructor ~SQLBuffer() { delete[] data_; } /// \brief Replace contents of buffer with copy of given C string SQLBuffer& assign(const char* data, size_type length, mysql_type_info type = mysql_type_info::string_type, bool is_null = false); /// \brief Replace contents of buffer with copy of given C++ string SQLBuffer& assign(const std::string& s, mysql_type_info type = mysql_type_info::string_type, bool is_null = false); /// \brief Return pointer to raw data buffer const char* data() const { return data_; } /// \brief Returns true if we were initialized with a data type /// that must be escaped when used in a SQL query bool escape_q() const { return type_.escape_q(); } /// \brief Return number of bytes in data buffer /// /// Count does not include the trailing null we tack on to our /// copy of the buffer for ease of use in C string contexts. /// We do this because we can be holding binary data just as /// easily as a C string. size_type length() const { return length_; } /// \brief Returns true if type of buffer's contents is string bool is_string() { return type_ == mysql_type_info::string_type; } /// \brief Return true if buffer's contents represent a SQL /// null. /// /// The buffer's actual content will probably be "NULL" or /// something like it, but in the SQL data type system, a SQL /// null is distinct from a plain string with value "NULL". bool is_null() const { return is_null_; } /// \brief Returns true if we were initialized with a data type /// that must be quoted when used in a SQL query bool quote_q() const; /// \brief Sets the internal SQL null flag void set_null() { is_null_ = true; } /// \brief Return the SQL type of the data held in the buffer const mysql_type_info& type() const { return type_; } private: SQLBuffer(const SQLBuffer&); SQLBuffer& operator=(const SQLBuffer&); /// \brief Common initialization for ctors void init(const char* pd, size_type len, mysql_type_info type, bool is_null); /// \brief Implementation detail of assign() and init() void replace_buffer(const char* pd, size_type length); const char* data_; ///< pointer to the raw data buffer size_type length_; ///< bytes in buffer, without trailing null mysql_type_info type_; ///< SQL type of data in the buffer bool is_null_; ///< if true, string represents a SQL null }; /// \brief Reference-counted version of SQLBuffer. /// /// No one uses SQLBuffer directly. It exists only for use in a /// RefCountedPointer wrapper. typedef RefCountedPointer<SQLBuffer> RefCountedBuffer; } // end namespace mysqlpp #endif // !defined(MYSQLPP_SQL_BUFFER_H) |
Deleted lib/sql_string.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/sql_string.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 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 | /// \file sql_types.h /// \brief Declares the closest C++ equivalent of each MySQL column type /// /// The typedefs defined here are only for the "non-NULL" variants. /// To get nullable versions, wrap the appropriate type in the /// \c Null<T> template. See null.h for more information. /*********************************************************************** Copyright (c) 2006-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_MAIN) #define MYSQLPP_SQL_TYPES_H_MAIN #include "common.h" #include "tiny_int.h" #include <string> #if !defined(MYSQLPP_NO_STDINT_H) # include <stdint.h> #endif namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Suppress refman documentation for these typedefs, as they're // system-dependent. // Define C++ integer types that are most nearly equivalent to those // used by the MySQL server. #if defined(MYSQLPP_NO_STDINT_H) // Boo, we're going to have to wing it. typedef tiny_int<signed char> sql_tinyint; typedef tiny_int<unsigned char> sql_tinyint_unsigned; typedef signed short sql_smallint; typedef unsigned short sql_smallint_unsigned; typedef signed int sql_int; typedef unsigned int sql_int_unsigned; typedef signed int sql_mediumint; typedef unsigned int sql_mediumint_unsigned; typedef longlong sql_bigint; typedef ulonglong sql_bigint_unsigned; #else // Assume a system where C99 is supported in C++ in advance of // actual standardization, so we can do this portably. typedef tiny_int<int8_t> sql_tinyint; typedef tiny_int<uint8_t> sql_tinyint_unsigned; typedef int16_t sql_smallint; typedef uint16_t sql_smallint_unsigned; typedef int32_t sql_int; typedef uint32_t sql_int_unsigned; typedef int32_t sql_mediumint; typedef uint32_t sql_mediumint_unsigned; typedef int64_t sql_bigint; typedef uint64_t sql_bigint_unsigned; #endif // Now define typedef equivalencies for the other standard MySQL // data types. There aren't serious portability issues here. typedef float sql_float; typedef double sql_double; typedef double sql_decimal; typedef std::string sql_enum; typedef std::string sql_char; typedef std::string sql_varchar; typedef std::string sql_tinytext; typedef std::string sql_text; typedef std::string sql_mediumtext; typedef std::string sql_longtext; // Aliases to match the rules MySQL uses in translating data types // from other database servers into its own type system. From: // http://dev.mysql.com/doc/refman/5.0/en/other-vendor-data-types.html typedef sql_tinyint sql_bool; typedef sql_tinyint sql_boolean; typedef sql_varchar sql_character_varying; typedef sql_decimal sql_fixed; typedef sql_float sql_float4; typedef sql_double sql_float8; typedef sql_tinyint sql_int1; typedef sql_smallint sql_int2; typedef sql_mediumint sql_int3; typedef sql_int sql_int4; typedef sql_bigint sql_int8; typedef sql_mediumtext sql_long_varchar; typedef sql_mediumtext sql_long; typedef sql_mediumint sql_middleint; typedef sql_decimal sql_numeric; #endif // !defined(DOXYGEN_IGNORE) } // end namespace mysqlpp #endif // !defined(MYSQLPP_SQL_TYPES_H_MAIN) // The following sections are treated separately to avoid making the // #include tree too dense: if mystring.h (for example) is not yet // #included, no sense pulling it in to define all the typedefs based // on String. The separate #include guards for each section allow // this file to be #included as many times as necessary to build up the // full typedef set. This trickery is necessary because sql_types.h // is needed in a few places within MySQL++, but we can't (and don't) // depend on having the full set of typedefs. mysql++.h #includes this // at a late stage, ensuring that end-user code does see the full set. #if defined(MYSQLPP_MYSTRING_H) && !defined(MYSQLPP_SQL_TYPES_H_MYSTRING) && !defined(DOXYGEN_IGNORE) # define MYSQLPP_SQL_TYPES_H_MYSTRING namespace mysqlpp { typedef String sql_blob; typedef String sql_tinyblob; typedef String sql_mediumblob; typedef String sql_longblob; typedef sql_mediumblob sql_long_varbinary; } // end namespace mysqlpp #endif #if defined(MYSQLPP_DATETIME_H) && !defined(MYSQLPP_SQL_TYPES_H_DATETIME) && !defined(DOXYGEN_IGNORE) # define MYSQLPP_SQL_TYPES_H_DATETIME namespace mysqlpp { typedef Date sql_date; typedef Time sql_time; typedef DateTime sql_timestamp; typedef DateTime sql_datetime; } // end namespace mysqlpp #endif #if defined(MYSQLPP_MYSET_H) && !defined(MYSQLPP_SQL_TYPES_H_SET) && !defined(DOXYGEN_IGNORE) # define MYSQLPP_SQL_TYPES_H_SET namespace mysqlpp { typedef Set<> sql_set; } // end namespace mysqlpp #endif #if defined(MYSQLPP_NULL_H) && !defined(MYSQLPP_SQL_TYPES_H_NULL) && !defined(DOXYGEN_IGNORE) # define MYSQLPP_SQL_TYPES_H_NULL // We have null.h, so define nullable versions of all the above namespace mysqlpp { typedef Null<sql_bigint> sql_bigint_null; typedef Null<sql_bigint_unsigned> sql_bigint_unsigned_null; typedef Null<sql_bool> sql_bool_null; typedef Null<sql_boolean> sql_boolean_null; typedef Null<sql_char> sql_char_null; typedef Null<sql_character_varying> sql_character_varying_null; typedef Null<sql_decimal> sql_decimal_null; typedef Null<sql_double> sql_double_null; typedef Null<sql_enum> sql_enum_null; typedef Null<sql_fixed> sql_fixed_null; typedef Null<sql_float> sql_float_null; typedef Null<sql_float4> sql_float4_null; typedef Null<sql_float8> sql_float8_null; typedef Null<sql_int> sql_int_null; typedef Null<sql_int1> sql_int1_null; typedef Null<sql_int2> sql_int2_null; typedef Null<sql_int3> sql_int3_null; typedef Null<sql_int4> sql_int4_null; typedef Null<sql_int8> sql_int8_null; typedef Null<sql_int_unsigned> sql_int_unsigned_null; typedef Null<sql_long> sql_long_null; typedef Null<sql_longtext> sql_longtext_null; typedef Null<sql_long_varchar> sql_long_varchar_null; typedef Null<sql_mediumint> sql_mediumint_null; typedef Null<sql_mediumint_unsigned> sql_mediumint_unsigned_null; typedef Null<sql_mediumtext> sql_mediumtext_null; typedef Null<sql_middleint> sql_middleint_null; typedef Null<sql_numeric> sql_numeric_null; typedef Null<sql_smallint> sql_smallint_null; typedef Null<sql_smallint_unsigned> sql_smallint_unsigned_null; typedef Null<sql_text> sql_text_null; typedef Null<sql_tinyint> sql_tinyint_null; typedef Null<sql_tinyint_unsigned> sql_tinyint_unsigned_null; typedef Null<sql_tinytext> sql_tinytext_null; typedef Null<sql_varchar> sql_varchar_null; // Also do nullable versions of optional sql_* types, where possible # if defined(MYSQLPP_SQL_TYPES_H_MYSTRING) typedef Null<sql_blob> sql_blob_null; typedef Null<sql_longblob> sql_longblob_null; typedef Null<sql_mediumblob> sql_mediumblob_null; typedef Null<sql_tinyblob> sql_tinyblob_null; typedef Null<sql_long_varbinary> sql_long_varbinary_null; # endif # if defined(MYSQLPP_SQL_TYPES_H_DATETIME) typedef Null<sql_date> sql_date_null; typedef Null<sql_datetime> sql_datetime_null; typedef Null<sql_time> sql_time_null; typedef Null<sql_timestamp> sql_timestamp_null; # endif # if defined(MYSQLPP_SQL_TYPES_H_SET) typedef Null<sql_set> sql_set_null; # endif } // end namespace mysqlpp #endif |
Added lib/sqlstream.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 | /*********************************************************************** sqlstream.cpp - Implements the SQLStream class. Copyright (c) 2008 by AboveNet, 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 "sqlstream.h" #include "dbdriver.h" #include "connection.h" #include <string> namespace mysqlpp { SQLStream::SQLStream(Connection* c, const char* pstr) : std::ostringstream(), conn_(c) { if (pstr != 0) { str(pstr); } } SQLStream::SQLStream(const SQLStream& s) : std::ostringstream(s.str()), conn_(s.conn_) { } size_t SQLStream::escape_string(std::string* ps, const char* original, size_t length) const { if (conn_ && *conn_) { // Normal case return conn_->driver()->escape_string(ps, original, length); } else { // Should only happen in test/test_manip.cpp, since it doesn't // want to open a DB connection just to test the manipulators. return DBDriver::escape_string_no_conn(ps, original, length); } } size_t SQLStream::escape_string(char* escaped, const char* original, size_t length) const { if (conn_ && *conn_) { // Normal case return conn_->driver()->escape_string(escaped, original, length); } else { // Should only happen in test/test_manip.cpp, since it doesn't // want to open a DB connection just to test the manipulators. return DBDriver::escape_string_no_conn(escaped, original, length); } } SQLStream& SQLStream::operator=(const SQLStream& rhs) { conn_ = rhs.conn_; str(rhs.str()); return *this; } } // end namespace mysqlpp |
Added lib/sqlstream.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 | /// \file sqlstream.h /// \brief Defines a class for building quoted and escaped SQL text. /*********************************************************************** Copyright (c) 2008 by AboveNet, 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_SQLSTREAM_H) #define MYSQLPP_SQLSTREAM_H #include "common.h" #include <sstream> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT Connection; #endif /// \brief A class for building SQL-formatted strings. /// /// See the user manual for more details about these options. class MYSQLPP_EXPORT SQLStream : public std::ostringstream { public: /// \brief Create a new stream object attached to a connection. /// /// \param c connection used for escaping text /// \param pstr an optional initial string SQLStream(Connection* c, const char* pstr = 0); /// \brief Create a new stream object as a copy of another. /// /// This is a traditional copy ctor. SQLStream(const SQLStream& s); /// \brief Return a SQL-escaped version of a character buffer /// /// \param ps pointer to C++ string to hold escaped version; if /// original is 0, also holds the original data to be escaped /// \param original if given, pointer to the character buffer to /// escape instead of contents of *ps /// \param length if both this and original are given, number of /// characters to escape instead of ps->length() /// /// \retval number of characters placed in *ps /// /// \see comments for escape_string(char*, const char*, size_t) /// and DBDriver::escape_string(std::string*, const char *, size_t) /// for further details. size_t escape_string(std::string* ps, const char* original = 0, size_t length = 0) const; /// \brief Return a SQL-escaped version of the given character /// buffer /// /// \param escaped character buffer to hold escaped version; must /// point to at least (length * 2 + 1) bytes /// \param original pointer to the character buffer to escape /// \param length number of characters to escape /// /// \retval number of characters placed in escaped /// /// DBDriver provides two versions of this method and /// Query::escape_string() calls the appropriate one based on whether /// or not a database connection is available. If the connection /// is available, it can call the DBDriver::escape_string() method. /// If there is no database connection available (normally only in /// testing), then DBDriver provides a static version of the function /// that doesn't use a database connection. /// /// \see comments for DBDriver::escape_string(char*, const char*, size_t), /// DBDriver::escape_string_no_conn(char*, const char*, size_t) /// for further details. size_t escape_string(char* escaped, const char* original, size_t length) const; /// \brief Assigns contents of another SQLStream to this one SQLStream& operator=(const SQLStream& rhs); /// \brief Connection to send queries through Connection* conn_; }; /// \brief Insert raw string into the given stream. /// /// This is just syntactic sugar for SQLStream::str(void) inline std::ostream& operator <<(std::ostream& os, SQLStream& s) { return os << s.str(); } } // end namespace mysqlpp #endif // !defined(MYSQLPP_SQLSTREAM_H) |
Added lib/ssqls.h.
more than 10,000 changes
Added lib/ssqls.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 | #!/usr/bin/perl -w ######################################################################## # ssqls.pl - Generates ssqls.h, as it defines many near-duplicate # functions and classes, varying only in trivial ways. # # Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and # (c) 2004-2010 by Educational Technology Resources, Inc. Others may # also hold copyrights on code in this file. See the CREDITS.txt 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 ssqls.h exponentially larger. This will increase compile # times and may even expose limits in your compiler. Increase it only # if and as far as you must. my $max_data_members = 25; # To make comparisons between floating point values, we subtract them, # take the absolute value, and test to see if that delta is under this # value. If it is, we call the two values "equal". Change this as fits # your need for precision. Note that we express it as a string because # we want the value copied literally into ssqls.h, not "preprocessed" # by Perl as a floating-point value. my $fp_min_delta = "0.00001"; # No user-serviceable parts below. use strict; use Getopt::Std; our $opt_f; getopts('f:') or die "usage: $0 [-f fields]\n\n"; $max_data_members = int($opt_f) if defined $opt_f; open (OUT, ">ssqls.h"); print OUT << "---"; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // This file is generated by the Perl script ssqls.pl. Do not modify // it directly. Change the script instead. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #if !defined(MYSQLPP_SSQLS_H) #define MYSQLPP_SSQLS_H #include "noexceptions.h" #include "sql_types.h" #if !defined(MYSQLPP_SSQLS_COMPATIBLE) # error Your compiler is not compatible with the SSQLS feature! #endif #include <string> #include <math.h> // Smallest difference between two floating point numbers recognized // in making comparisons. If the absolute delta is under this // threshold, the two values are considered equal. You can either // override this permanently by changing ssqls.pl, or you can do it // on a case-by-case basis at compile time by defining this to another // value before #including this header. #if !defined(MYSQLPP_FP_MIN_DELTA) # define MYSQLPP_FP_MIN_DELTA $fp_min_delta #endif namespace mysqlpp { enum sql_dummy_type { sql_dummy }; #ifdef MYSQLPP_SSQLS_NO_STATICS # define MYSQLPP_SSQLS_CONDITIONAL_STATICS(...) #else # define MYSQLPP_SSQLS_CONDITIONAL_STATICS(...) __VA_ARGS__ #endif #define MYSQLPP_SSQLS_MAX_MEMBERS $max_data_members --- my @types = ("Date", "DateTime", "Time", "String", "std::string"); foreach my $type (@types) { print OUT << "---"; inline int sql_cmp(const $type& a, const $type& b) { return a.compare(b); } --- } @types = ( "signed char", "unsigned char", "sql_tinyint", "sql_tinyint_unsigned", "signed int", "unsigned", "signed short", "unsigned short", "signed long", "unsigned long"); foreach my $type (@types) { print OUT << "---"; inline int sql_cmp($type a, $type b) { return a - b; } --- } @types = ("longlong", "ulonglong"); foreach my $type (@types) { print OUT << "---"; inline int sql_cmp($type a, $type b) { if (a == b) return 0; if (a < b) return -1; return 1; } --- } @types = ("double", "float"); foreach my $type (@types) { print OUT << "---"; inline int sql_cmp($type a, $type b) { if (fabs(a - b) < MYSQLPP_FP_MIN_DELTA) return 0; if (a < b) return -1; return 1; } --- } print OUT << "---"; template <typename T> inline int sql_cmp(const mysqlpp::Null<T>& a, const mysqlpp::Null<T>& b) { if (a == b) return 0; if (a < b) return -1; return 1; } // --------------------------------------------------- // 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, table_override_(0) {} \\ void set($parm2) { \\ table_override_ = 0; \\ $set \\ } \\ sql_compare_define(NAME) #define sql_construct_define_$i(NAME, $parm0) \\ void set($parm2) { \\ table_override_ = 0; \\ $set \\ } \\ NAME($parm2) : $define, table_override_(0) {} #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 // --------------------------------------------------- --- } foreach my $i (1..$max_data_members) { my $create_bool = ""; my $create_list = ""; my $cus_equal_list = ""; my $cus_field_list = ""; my $cusparms1 = ""; my $cusparms11 = ""; my $cusparms2 = ""; my $cusparms22 = ""; my $cusparmsv = ""; my $defs = ""; my $enums = ""; my $equal_list = ""; my $field_list = ""; my $names = ""; my $parmc = ""; my $parmC = ""; my $parm_complete = ""; my $parm_simple = ""; my $parm_simple2c = ""; my $parm_simple2c_b = ""; my $parm_simple_b = ""; my $popul = ""; my $value_list = ""; my $value_list_cus = ""; foreach my $j (1 .. $i) { $parm_complete .= "T$j, I$j, N$j"; $parm_complete .= ", " unless $j == $i; $parm_simple .= "T$j, I$j"; $parm_simple .= ", " unless $j == $i; $parm_simple2c .= "T$j, I$j, #I$j"; $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"; $parm_simple2c_b .= ", " unless $j == $i; $defs .= " T$j I$j;"; $defs .= "\n" unless $j == $i; $popul .= " s->I$j = row[N$j].conv(T$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.delim;\n" unless $j == $i; $value_list .= " s << obj.manip << obj.obj->I$j"; $value_list .= " << obj.delim;\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.delim;\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.delim;\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.delim;\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.delim;\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_complete_$i(NAME, CMP, CONTR, $parm_complete) struct NAME; enum NAME##_enum { $enums ,NAME##_NULL }; template <class Manip> class NAME##_value_list { public: const NAME* obj; const char* delim; Manip manip; public: NAME##_value_list (const NAME* o, const char* d, Manip m) : obj(o), delim(d), manip(m) { } }; template <class Manip> class NAME##_##field_list { public: const NAME* obj; const char* delim; Manip manip; public: NAME##_field_list (const NAME* o, const char* d, Manip m) : obj(o), delim(d), manip(m) { } }; template <class Manip> class NAME##_equal_list { public: const NAME* obj; const char* delim; const char* comp; Manip manip; public: NAME##_equal_list (const NAME* o, const char* d, const char* c, Manip m) : obj(o), delim(d), comp(c), manip(m) { } }; template <class Manip> class NAME##_cus_value_list { public: const NAME* obj; std::vector<bool> *include; bool del_vector; const char* delim; Manip manip; public: ~NAME##_cus_value_list () {if (del_vector) delete include;} NAME##_cus_value_list (const NAME* o, const char* d, Manip m, $cusparms11); NAME##_cus_value_list (const NAME* o, const char* d, Manip m, $cusparms22); NAME##_cus_value_list (const NAME* o, const char* d, Manip m ,std::vector<bool>* i) : obj(o), include(i), del_vector(false), delim(d), manip(m) { } }; template <class Manip> class NAME##_cus_field_list { public: const NAME* obj; std::vector<bool> *include; bool del_vector; const char* delim; Manip manip; public: ~NAME##_cus_field_list () {if (del_vector) delete include;} NAME##_cus_field_list (const NAME* o, const char* d, Manip m, $cusparms11); NAME##_cus_field_list (const NAME* o, const char* d, Manip m, $cusparms22); NAME##_cus_field_list (const NAME* o, const char* d, Manip m, std::vector<bool> *i) : obj(o), include(i), del_vector(false), delim(d), manip(m) { } }; template <class Manip> class NAME##_cus_equal_list { public: const NAME* obj; std::vector<bool> *include; bool del_vector; const char* delim; const char* comp; Manip manip; public: ~NAME##_##cus_equal_list () {if (del_vector) delete include;} NAME##_##cus_equal_list (const NAME* o, const char* d, const char* c, Manip m, $cusparms11); NAME##_##cus_equal_list (const NAME* o, const char* d, const char* c, Manip m, $cusparms22); NAME##_##cus_equal_list (const NAME* o, const char* d, const char* c, Manip m, std::vector<bool> *i) : obj(o), include(i), del_vector(false), delim(d), comp(c), manip(m) { } }; template <mysqlpp::sql_dummy_type dummy> int sql_compare_##NAME(const NAME&, const NAME&); struct NAME { $defs NAME() : table_override_(0) { } 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 void table(const char* t) { table_ = t; } const char* table() const { return table_override_ ? table_override_ : NAME::table_; } void instance_table(const char* t) { table_override_ = t; } NAME##_value_list<mysqlpp::quote_type0> value_list() const { return value_list(",", mysqlpp::quote);} NAME##_value_list<mysqlpp::quote_type0> value_list(const char* d) const { return value_list(d, mysqlpp::quote);} template <class Manip> NAME##_value_list<Manip> value_list(const char* 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(const char* d) const { return field_list(d, mysqlpp::do_nothing);} template <class Manip> NAME##_field_list<Manip> field_list(const char* d, Manip m) const; NAME##_equal_list<mysqlpp::quote_type0> equal_list(const char* d = ",", const char* c = " = ") const { return equal_list(d, c, mysqlpp::quote); } template <class Manip> NAME##_equal_list<Manip> equal_list(const char* d, const char* 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(const char* d, $cusparms1) const { return value_list(d, mysqlpp::quote, $cusparmsv); } NAME##_cus_value_list<mysqlpp::quote_type0> value_list(const char* d, $cusparms2) const { return value_list(d, mysqlpp::quote, $cusparmsv); } NAME##_cus_value_list<mysqlpp::quote_type0> value_list(const char* d, std::vector<bool> *i) const { return value_list(d, mysqlpp::quote, i); } NAME##_cus_value_list<mysqlpp::quote_type0> value_list(const char* d, mysqlpp::sql_cmp_type sc) const { return value_list(d, mysqlpp::quote, sc); } template <class Manip> NAME##_cus_value_list<Manip> value_list(const char* d, Manip m, $cusparms1) const; template <class Manip> NAME##_cus_value_list<Manip> value_list(const char* d, Manip m, $cusparms2) const; template <class Manip> NAME##_cus_value_list<Manip> value_list(const char* d, Manip m, std::vector<bool>* i) const; template <class Manip> NAME##_cus_value_list<Manip> value_list(const char* 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(const char* d, $cusparms1) const { return field_list(d, mysqlpp::do_nothing, $cusparmsv); } NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(const char* d, $cusparms2) const { return field_list(d, mysqlpp::do_nothing, $cusparmsv); } NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(const char* d, std::vector<bool>* i) const { return field_list(d, mysqlpp::do_nothing, i); } NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(const char* 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(const char* d, Manip m, $cusparms1) const; template <class Manip> NAME##_cus_field_list<Manip> field_list(const char* d, Manip m, $cusparms2) const; template <class Manip> NAME##_cus_field_list<Manip> field_list(const char* d, Manip m, std::vector<bool> *i) const; template <class Manip> NAME##_cus_field_list<Manip> field_list(const char* 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(const char* d, $cusparms1) const { return equal_list(d, " = ", mysqlpp::quote, $cusparmsv); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, $cusparms2) const { return equal_list(d, " = ", mysqlpp::quote, $cusparmsv); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, std::vector<bool> *i) const { return equal_list(d, " = ", mysqlpp::quote, i); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, mysqlpp::sql_cmp_type sc) const { return equal_list(d, " = ", mysqlpp::quote, sc); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, const char* c, $cusparms1) const { return equal_list(d, c, mysqlpp::quote, $cusparmsv); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, const char* c, $cusparms2) const { return equal_list(d, c, mysqlpp::quote, $cusparmsv); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, const char* c, std::vector<bool> *i) const { return equal_list(d, c, mysqlpp::quote, i); } NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(const char* d, const char* 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(const char* d, const char* c, Manip m, $cusparms1) const; template <class Manip> NAME##_cus_equal_list<Manip> equal_list(const char* d, const char* c, Manip m, $cusparms2) const; template <class Manip> NAME##_cus_equal_list<Manip> equal_list(const char* d, const char* c, Manip m, std::vector<bool> *i) const; template <class Manip> NAME##_cus_equal_list<Manip> equal_list(const char* d, const char* c, Manip m, mysqlpp::sql_cmp_type sc) const; private: static const char* table_; const char* table_override_; }; MYSQLPP_SSQLS_CONDITIONAL_STATICS( const char* NAME::names[] = { $names }; const char* NAME::table_ = #NAME; ) template <class Manip> NAME##_cus_value_list<Manip>::NAME##_cus_value_list (const NAME* o, const char* d, Manip m, $cusparms11) { delim = 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, const char* d, Manip m, $cusparms22) { delim = 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, const char* d, Manip m, $cusparms11) { delim = 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, const char* d, Manip m, $cusparms22) { delim = 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, const char* d, const char* c, Manip m, $cusparms11) { delim = 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, const char* d, const char* c, Manip m, $cusparms22) { delim = 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(const char* d, Manip m) const { return NAME##_value_list<Manip> (this, d, m); } template <class Manip> inline NAME##_field_list<Manip> NAME::field_list(const char* d, Manip m) const { return NAME##_field_list<Manip> (this, d, m); } template <class Manip> inline NAME##_equal_list<Manip> NAME::equal_list(const char* d, const char* 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(const char* 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(const char* 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(const char* d, const char* 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(const char* 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(const char* 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(const char* d, const char* 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(const char* 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(const char* 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(const char* d, const char* 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(const char* 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(const char* 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(const char* d, const char* 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) { mysqlpp::NoExceptions ignore_schema_mismatches(row); $popul } inline NAME::NAME(const mysqlpp::Row& row) : table_override_(0) { populate_##NAME<mysqlpp::sql_dummy>(this, row); } inline void NAME::set(const mysqlpp::Row& row) { table_override_ = 0; populate_##NAME<mysqlpp::sql_dummy>(this, row); } sql_COMPARE__##CMP(NAME, $parmc ) --- print OUT &prepare($out); # # short cut defs # print OUT << "---"; #define sql_create_$i(NAME, CMP, CONTR, $parm_simple) \\ sql_create_complete_$i(NAME, CMP, CONTR, $parm_simple2c) \\ // --------------------------------------------------- // End Create $i // --------------------------------------------------- --- } print OUT << "---"; } // end namespace mysqlpp #endif // !defined(MYSQLPP_SSQLS_H) --- sub prepare { local $_ = $_[0]; s/\n+$//; s/\n[\n ]*\n/\n/g; s/\n+/\\\n/g; $_ .= "\n\n"; return $_; } |
Added lib/ssqls2.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 | /*********************************************************************** ssqls2.cpp - Implements the SsqlsBase class. Copyright (c) 2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "ssqls2.h" #include "connection.h" #include "exceptions.h" #include "query.h" using namespace std; // All of the Active Record calls below follow a common pattern, which // we can only express as a macro. They just wrap similar calls in // Query, varying only in minor per-call specific details. #define QUERY_ACTIVE_RECORD_WRAPPER(action, conn, fs) \ if (conn) conn_ = conn; \ if (conn_) { \ if (conn_->connected()) { \ if (populated(fs)) return conn_->query().action(*this).execute(); \ else if (conn_->throw_exceptions()) throw BadQuery( \ "Cannot " #action " insufficiently populated SSQLS"); \ else return false; \ } \ else if (conn_->throw_exceptions()) throw ConnectionFailed( \ "Cannot " #action " SSQLS without established connection"); \ else return false; \ } \ else throw ObjectNotInitialized(typeid(*this).name()); namespace mysqlpp { bool SsqlsBase::create(Connection* conn) const { (void)conn; //TODO define Query::insert(SsqlsBase&) //QUERY_ACTIVE_RECORD_WRAPPER(insert, conn, fs_not_autoinc); return false; } bool SsqlsBase::load(Connection* conn) const { (void)conn; //TODO define Query::select(SsqlsBase&) //QUERY_ACTIVE_RECORD_WRAPPER(select, conn, fs_key); return false; } bool SsqlsBase::remove(Connection* conn) const { (void)conn; //TODO define Query::remove(SsqlsBase&) //QUERY_ACTIVE_RECORD_WRAPPER(remove, conn, fs_key); return false; } bool SsqlsBase::save(Connection* conn) const { (void)conn; //TODO define Query::update(SsqlsBase&) //QUERY_ACTIVE_RECORD_WRAPPER(update, conn, fs_all); return false; } } // end namespace mysqlpp |
Added lib/ssqls2.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 | /// \file ssqls2.h /// \brief Declares the SsqlsBase class /*********************************************************************** Copyright (c) 2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_SSQLS2_H) #define MYSQLPP_SSQLS2_H #include "common.h" #include <iostream> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) // Make Doxygen ignore this class MYSQLPP_EXPORT Connection; class MYSQLPP_EXPORT Row; #endif /// \brief Base class for all SSQLSv2 classes /// /// Classes generated by ssqlsxlat derive from this class. It is not /// directly instantiable. It exists only to hold the common interface /// to all SSQLSv2 classes. class MYSQLPP_EXPORT SsqlsBase { public: /// \brief Supported field subsets enum FieldSubset { fs_all, ///< all fields fs_key, ///< fields with "is key" attribute fs_set, ///< fields that have been given a value fs_not_autoinc ///< fields without "is autoinc" attribute }; /// \brief Create table in database matching subclass schema /// /// \param conn If given, use this connection instead of the one we /// may have gotten earlier; saves value for future use. /// /// \return true if table was successfully created; on failure, /// only returns false if conn->throw_exceptions() is false. virtual bool create_table(Connection* conn = 0) const = 0; /// \brief Create record in database from all fields in object /// except for any marked as auto-increment. /// /// \param conn If given, use this connection instead of the one we /// may have gotten earlier; saves value for future use. /// /// \return true if new record was successfully created; on failure, /// only returns false if conn->throw_exceptions() is false. bool create(Connection* conn = 0) const; /// \brief Puts stream insertion operator into "equal list" mode /// /// Typical usage: /// /// \code cout << foo.equal_list() << endl; /// /// \see operator<<(std::ostream&, const SsqlsBase&) const SsqlsBase& equal_list() const { output_mode_ = om_equal_list; return *this; } /// \brief Insert SSQLS's names and values into a stream. /// /// An "equal list" is a set of name/value pairs in SQL assignment /// form, suitable for building INSERT queries and such. /// /// \param os output stream to insert equal list into /// \param fs with default value, only the fields that have been /// given values are included in the output virtual std::ostream& equal_list(std::ostream& os, FieldSubset fs = fs_set) const = 0; /// \brief Set a per-instance SQL table name /// /// This causes table() to return the passed value instead of the /// static per-class value it normally returns. This is useful if /// you're using a single SSQLS definition for multiple tables that /// happen to share a common schema or schema subset. void instance_table(const char* name) { instance_table_name_ = name; } /// \brief Retrieve record from the database matching our key field(s) /// /// \param conn If given, use this connection instead of the one we /// may have gotten earlier; saves value for future use. /// /// \return true if record was successfully retrieved; on failure, /// only returns false if conn->throw_exceptions() is false. bool load(Connection* conn = 0) const; /// \brief Puts stream insertion operator into "name list" mode /// /// Typical usage: /// /// \code cout << foo.name_list() << endl; /// /// \see operator<<(std::ostream&, const SsqlsBase&) const SsqlsBase& name_list() const { output_mode_ = om_name_list; return *this; } /// \brief Insert the SSQLS's field names into a stream /// /// A "name list" is a comma-separated list of SSQLS field names /// /// \param os output stream to insert name list into /// \param fs with default value, only the names of fields that have /// been given values are included in the output virtual std::ostream& name_list(std::ostream& os, FieldSubset fs = fs_set) const = 0; /// \brief Returns truthy value if object's fields have been fully /// populated. /// /// Test the Row, result or Query class you used to assign the /// value to distinguish a successful subset population from /// a complete failure to populate the object. Because of this /// ambiguity, this operator is only useful for checking that an /// expected full population did in fact fully populate the object. /// This can help you to detect schema drift. operator const void*() const { return populated() ? this : 0; } /// \brief Returns true if the object has been populated /// /// \param fs field subset to check, defaulting to "all fields" /// /// This can give a different result than testing the object in /// bool context if you pass something other than fs_all. virtual bool populated(FieldSubset fs = fs_all) const = 0; /// \brief Delete record matching our key field(s) from the database /// /// \param conn If given, use this connection instead of the one we /// may have gotten earlier; saves value for future use. /// /// \return true if record was successfully removed; on failure, /// only returns false if conn->throw_exceptions() is false. bool remove(Connection* conn = 0) const; /// \brief Update record in database matching our key fields, or /// insert it if there is no such record. /// /// \param conn If given, use this connection instead of the one we /// may have gotten earlier; saves value for future use. /// /// \return true if record was successfully saved; on failure, /// only returns false if conn->throw_exceptions() is false. bool save(Connection* conn = 0) const; /// \brief Get the object's SQL table name /// /// \r return the value set by instance_table(), if you called it, /// or a static per-class value otherwise const char* table() const { return instance_table_name_; } /// \brief Puts stream insertion operator into "value list" mode /// /// Typical usage: /// /// \code cout << foo.value_list() << endl; /// /// \see operator<<(std::ostream&, const SsqlsBase&) const SsqlsBase& value_list() const { output_mode_ = om_value_list; return *this; } /// \brief Insert SSQLS's values into a stream. /// /// A "value list" is a comma-separated list of SSQLS field values. /// Whether the values are quoted and/or escaped depends on the /// stream type passed for os. /// /// \param os output stream to insert value list into /// \param fs with default value, only the fields that have been /// given values are included in the output virtual std::ostream& value_list(std::ostream& os, FieldSubset fs = fs_set) const = 0; protected: /// \brief Default constructor /// /// \param conn pointer to connection we should use for Active /// Record methods' queries, if no connection is passed for that /// particular call. SsqlsBase(Connection* conn = 0) : output_mode_(om_value_list), conn_(conn), instance_table_name_(0) { } /// \brief Full initialization constructor /// /// \param row data to use in initializing SSQLS fields /// \param conn pointer to connection we should use for Active /// Record methods' queries, if no connection is passed for that /// particular call. /// \todo do something with row parameter SsqlsBase(const Row& row, Connection* conn = 0) : output_mode_(om_value_list), conn_(conn), instance_table_name_(0) { #if !defined(_MSC_VER) // Unused parameter warning squisher. VC++ can't cope without // including row.h, which we don't want to do just to squish a // warning. It doesn't warn anyway, so... (void)row; #endif } /// \brief Destructor virtual ~SsqlsBase() { } /// \brief Flag controlling the behavior of operator<<() mutable enum { om_equal_list, om_name_list, om_value_list } output_mode_; /// \brief Connection object we were initialized from, if any /// /// This just provides a default for the Active Record methods /// above that take Connection*. mutable Connection* conn_; private: /// \brief Table name override for this particular object const char* instance_table_name_; friend std::ostream& operator <<(std::ostream&, const SsqlsBase&); }; /// \brief Put contents of an SSQLSv2 derivative into a \c std::ostream /// /// If you use this operator directly, you get a comma-separated list of /// field values in the ostream. Whether those values are quoted and/or /// escaped depends on the ostream type. /// /// It is also useful to use this operator indirectly, via /// SsqlsBase::equal_list() or SsqlsBase::name_list(). (There is also a /// SsqlsBase::value_list(), but it's just an alias for calling this operator /// directly.) These methods set a flag on the object that causes this /// operator to insert an equals list (e.g. "name1 = value1, name2 = /// value2...") or a name list into the stream. The flag is immediately /// reset to give value lists again on completion of the insert operation. /// For example: /// /// \code /// stock s = ...; // initialize an SSQLSv2 object of 'stock' class /// cout << "Set field names: " << s.name_list() << endl; /// \endcode /// /// The \c s.name_list() call sets the output mode to "names", then passes /// \c cout and \c *this to this operator, which then calls the version /// of s.name_list() taking a stream reference, which is overridden in /// the leaf class to know how to insert the names of all fields set on /// the \c s object. /// /// \param os IOstream to insert object contents into /// \param sb object to insert into the stream std::ostream& operator <<(std::ostream& os, const SsqlsBase& sb) { switch (sb.output_mode_) { case SsqlsBase::om_equal_list: sb.equal_list(os); break; case SsqlsBase::om_name_list: sb.name_list(os); break; case SsqlsBase::om_value_list: sb.value_list(os); break; } sb.output_mode_ = SsqlsBase::om_value_list; return os; } } // end namespace mysqlpp #endif // !defined(MYSQLPP_SSQLS2_H) |
Added lib/stadapter.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 | /*********************************************************************** stadapter.cpp - Implements the SQLTypeAdapter class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "stadapter.h" #include "mystring.h" #include "refcounted.h" #include "stream2string.h" #include <iomanip> #include <limits> #include <sstream> using namespace std; namespace mysqlpp { SQLTypeAdapter::SQLTypeAdapter() : is_processed_(false) { } SQLTypeAdapter::SQLTypeAdapter(const SQLTypeAdapter& other) : buffer_(other.buffer_), is_processed_(false) { } SQLTypeAdapter::SQLTypeAdapter(const String& other, bool processed) : buffer_(other.buffer_), is_processed_(processed) { } SQLTypeAdapter::SQLTypeAdapter(const std::string& str, bool processed) : buffer_(new SQLBuffer(str, mysql_type_info::string_type, false)), is_processed_(processed) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(const Null<string>& str, bool processed) : buffer_(new SQLBuffer(str.is_null ? null_str : str.data, str.is_null ? typeid(void) : typeid(str.data), str.is_null)), is_processed_(processed) { } SQLTypeAdapter::SQLTypeAdapter(const Null<String>& str, bool processed) : buffer_(new SQLBuffer( str.is_null ? null_str.c_str() : str.data.data(), str.is_null ? null_str.length() : str.data.length(), str.is_null ? typeid(void) : typeid(str.data), str.is_null)), is_processed_(processed) { } #endif SQLTypeAdapter::SQLTypeAdapter(const char* str, bool processed) : buffer_(new SQLBuffer(str, strlen(str), mysql_type_info::string_type, false)), is_processed_(processed) { } SQLTypeAdapter::SQLTypeAdapter(const char* str, int len, bool processed) : buffer_(new SQLBuffer(str, len, mysql_type_info::string_type, false)), is_processed_(processed) { } SQLTypeAdapter::SQLTypeAdapter(char c) : buffer_(new SQLBuffer(stream2string(c), mysql_type_info::string_type, false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<char> c) : buffer_(new SQLBuffer(c.is_null ? null_str : stream2string(c), c.is_null ? typeid(void) : typeid(c.data), c.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(tiny_int<signed char> i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<tiny_int<signed char> > i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(tiny_int<unsigned char> i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<tiny_int<unsigned char> > i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(short i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<short> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(unsigned short i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<unsigned short> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(int i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<int> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(unsigned i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<unsigned> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(long i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<long> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(unsigned long i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<unsigned long> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(longlong i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<longlong> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(ulonglong i) : buffer_(new SQLBuffer(stream2string(i), typeid(i), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<ulonglong> i) : buffer_(new SQLBuffer(i.is_null ? null_str : stream2string(i), i.is_null ? typeid(void) : typeid(i.data), i.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(float f) : is_processed_(false) { typedef numeric_limits<float> nlf; if ((nlf::has_infinity && (f == nlf::infinity())) || (nlf::has_quiet_NaN && (f == nlf::quiet_NaN())) || (nlf::has_signaling_NaN && (f == nlf::signaling_NaN()))) { // f isn't null-able, but it's infinite or NaN, so store it // as a 0. This at least prevents syntactically-invalid SQL. buffer_ = new SQLBuffer("0", typeid(f), true); } else { ostringstream outs; outs.precision(9); // max dec digits needed for IEEE 754 32-bit float outs << f; buffer_ = new SQLBuffer(outs.str(), typeid(f), false); } } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<float> f) : is_processed_(false) { typedef numeric_limits<float> nlf; if (f.is_null || (nlf::has_infinity && (f.data == nlf::infinity())) || (nlf::has_quiet_NaN && (f.data == nlf::quiet_NaN())) || (nlf::has_signaling_NaN && (f.data == nlf::signaling_NaN()))) { // MySQL wants infinite and NaN FP values stored as SQL NULL buffer_ = new SQLBuffer(null_str, typeid(void), true); } else { ostringstream outs; outs.precision(9); // as above outs << f; buffer_ = new SQLBuffer(outs.str(), typeid(f.data), false); } } #endif SQLTypeAdapter::SQLTypeAdapter(double f) : is_processed_(false) { typedef numeric_limits<double> nld; if ((nld::has_infinity && (f == nld::infinity())) || (nld::has_quiet_NaN && (f == nld::quiet_NaN())) || (nld::has_signaling_NaN && (f == nld::signaling_NaN()))) { // f isn't null-able, but it's infinite or NaN, so store it // as a 0. This at least prevents syntactically-invalid SQL. buffer_ = new SQLBuffer("0", typeid(f), true); } else { ostringstream outs; outs.precision(17); // max dec digits needed for IEEE 754 64-bit float outs << f; buffer_ = new SQLBuffer(outs.str(), typeid(f), false); } } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(Null<double> f) : is_processed_(false) { typedef numeric_limits<double> nld; if (f.is_null || (nld::has_infinity && (f.data == nld::infinity())) || (nld::has_quiet_NaN && (f.data == nld::quiet_NaN())) || (nld::has_signaling_NaN && (f.data == nld::signaling_NaN()))) { // MySQL wants infinite and NaN FP values stored as SQL NULL buffer_ = new SQLBuffer(null_str, typeid(void), true); } else { ostringstream outs; outs.precision(17); // as above outs << f; buffer_ = new SQLBuffer(outs.str(), typeid(f.data), false); } } #endif SQLTypeAdapter::SQLTypeAdapter(const Date& d) : buffer_(new SQLBuffer(stream2string(d), typeid(d), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(const Null<Date>& d) : buffer_(new SQLBuffer(d.is_null ? null_str : stream2string(d), d.is_null ? typeid(void) : typeid(d.data), d.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(const DateTime& dt) : buffer_(new SQLBuffer(stream2string(dt), typeid(dt), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(const Null<DateTime>& dt) : buffer_(new SQLBuffer(dt.is_null ? null_str : stream2string(dt), dt.is_null ? typeid(void) : typeid(dt.data), dt.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(const Time& t) : buffer_(new SQLBuffer(stream2string(t), typeid(t), false)), is_processed_(false) { } #if !defined(DOXYGEN_IGNORE) SQLTypeAdapter::SQLTypeAdapter(const Null<Time>& t) : buffer_(new SQLBuffer(t.is_null ? null_str : stream2string(t), t.is_null ? typeid(void) : typeid(t.data), t.is_null)), is_processed_(false) { } #endif SQLTypeAdapter::SQLTypeAdapter(const null_type&) : buffer_(new SQLBuffer(null_str, typeid(void), true)), is_processed_(false) { } SQLTypeAdapter& SQLTypeAdapter::assign(const SQLTypeAdapter& sta) { buffer_ = sta.buffer_; is_processed_ = false; return *this; } SQLTypeAdapter& SQLTypeAdapter::assign(const char* pc, int len) { if (len < 0) { len = int(strlen(pc)); } buffer_ = new SQLBuffer(pc, len, mysql_type_info::string_type, false); is_processed_ = false; return *this; } SQLTypeAdapter& SQLTypeAdapter::assign(const null_type&) { buffer_ = new SQLBuffer(null_str, typeid(void), true); is_processed_ = false; return *this; } char SQLTypeAdapter::at(size_type i) const throw(std::out_of_range) { if (buffer_) { if (i <= length()) { return *(buffer_->data() + i); } else { throw BadIndex("Not enough chars in SQLTypeAdapter", int(i), int(length())); } } else { throw BadIndex("SQLTypeAdapter buffer not initialized", int(i), -1); } } int SQLTypeAdapter::compare(const SQLTypeAdapter& other) const { if (other.buffer_) { return compare(0, length(), other.buffer_->data()); } else { return buffer_ ? 1 : 0; } } int SQLTypeAdapter::compare(const std::string& other) const { return compare(0, length(), other.data()); } int SQLTypeAdapter::compare(size_type pos, size_type num, std::string& other) const { return compare(pos, num, other.data()); } int SQLTypeAdapter::compare(const char* other) const { return compare(0, length(), other); } int SQLTypeAdapter::compare(size_type pos, size_type num, const char* other) const { if (buffer_ && other) { return strncmp(data() + pos, other, num); } else if (!other) { return 1; // initted is "greater than" uninitted } else { return other ? -1 : 0; // "less than" unless other also unitted } } const char* SQLTypeAdapter::data() const { return buffer_ ? buffer_->data() : 0; } SQLTypeAdapter::size_type SQLTypeAdapter::length() const { return buffer_ ? buffer_->length() : 0; } bool SQLTypeAdapter::escape_q() const { return buffer_ ? buffer_->escape_q() : false; } SQLTypeAdapter& SQLTypeAdapter::operator =(const SQLTypeAdapter& rhs) { return assign(rhs); } SQLTypeAdapter& SQLTypeAdapter::operator =(const null_type& n) { return assign(n); } bool SQLTypeAdapter::quote_q() const { // If no buffer, it means we're an empty string, so we need to be // quoted to be expressed properly in SQL. return buffer_ ? buffer_->quote_q() : true; } int SQLTypeAdapter::type_id() const { return buffer_ ? buffer_->type().id() : 0; } } // end namespace mysqlpp |
Added lib/stadapter.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 | /// \file stadapter.h /// \brief Declares the SQLTypeAdapter class /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and (c) 2004-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_TYPE_ADAPTER_H) #define MYSQLPP_SQL_TYPE_ADAPTER_H #include "common.h" #include "datetime.h" #include "null.h" #include "sql_buffer.h" #include "tiny_int.h" #include <stdexcept> #include <string> namespace mysqlpp { #if !defined(DOXYGEN_IGNORE) class MYSQLPP_EXPORT String; #endif /// \brief Converts many different data types to strings suitable for /// use in SQL queries. /// /// This class provides implicit conversion between many C++ types and /// SQL-formatted string representations of that data without losing /// important type information. This class is not for direct use /// outside MySQL++ itself. It exists for those interfaces in MySQL++ /// that need to accept a value of any reasonable data type which it /// will use in building a query string. /// /// One major use for this is in the Query class interfaces for building /// template queries: they have to be generic with respect to argument /// type, but because we know we want the data in some kind of string /// form eventually, we don't need to templatize it. The interface can /// just use SQLTypeAdapter, which lets callers pass any reasonable data /// type. The adapter converts the passed value implicitly. /// /// The other major use for this type is the quoting and escaping logic /// in Query's stream interface: rather than overload the << operators /// and the manipulators for every single type we know the rules for \e a /// \e priori, we just specialize the manipulators for SQLTypeAdapter. /// The conversion to SQLTypeAdapter stringizes the data, which we needed /// anyway for stream insertion, and holds enough type information so /// that the manipulator can decide whether to do automatic quoting /// and/or escaping. class MYSQLPP_EXPORT SQLTypeAdapter { public: typedef size_t size_type; ///< size of length values /// \brief Default constructor; empty string SQLTypeAdapter(); /// \brief Copy ctor /// /// \param other the other SQLTypeAdapter object /// /// This ctor only copies the pointer to the other SQLTypeAdapter's /// data buffer and increments its reference counter. If you need a /// deep copy, use one of the ctors that takes a string. SQLTypeAdapter(const SQLTypeAdapter& other); /// \brief Create a copy of a MySQL++ string /// /// This does reference-counted buffer sharing with the other /// object. If you need a deep copy, pass the result of /// either String::c_str() or String::conv() instead, which will /// call one of the other string ctors. SQLTypeAdapter(const String& str, bool processed = false); /// \brief Create a copy of a C++ string SQLTypeAdapter(const std::string& str, bool processed = false); /// \brief Create a copy of a null-terminated C string SQLTypeAdapter(const char* str, bool processed = false); /// \brief Create a copy of an arbitrary block of data SQLTypeAdapter(const char* str, int len, bool processed = false); /// \brief Create a single-character string /// /// If you mean for \c c to be treated as a small integer, you /// should be using mysqlpp::tiny_int instead. It avoids the /// confusion in C++ between integer and character. See the /// documentation for tiny_int.h for details. SQLTypeAdapter(char c); /// \brief Create a string representation of SQL \c TINYINT SQLTypeAdapter(tiny_int<signed char> i); /// \brief Create a string representation of SQL \c TINYINT /// \c UNSIGNED SQLTypeAdapter(tiny_int<unsigned char> i); /// \brief Create a string representation of a \c short \c int value SQLTypeAdapter(short i); /// \brief Create a string representation of an \c unsigned /// \c short \c int value SQLTypeAdapter(unsigned short i); /// \brief Create a string representation of an \c int value SQLTypeAdapter(int i); /// \brief Create a string representation of an \c unsigned \c int /// value SQLTypeAdapter(unsigned i); /// \brief Create a string representation of a \c long \c int value SQLTypeAdapter(long i); /// \brief Create a string representation of an \c unsigned /// \c long \c int value SQLTypeAdapter(unsigned long i); /// \brief Create a string representation of a \c longlong value SQLTypeAdapter(longlong i); /// \brief Create a string representation of an \c unsigned /// \c longlong value SQLTypeAdapter(ulonglong i); /// \brief Create a string representation of a \c float value SQLTypeAdapter(float i); /// \brief Create a string representation of a \c double value SQLTypeAdapter(double i); /// \brief Create a SQL string representation of a date SQLTypeAdapter(const Date& d); /// \brief Create a SQL string representation of a date and time SQLTypeAdapter(const DateTime& dt); /// \brief Create a SQL string representation of a time SQLTypeAdapter(const Time& t); /// \brief Create object representing SQL NULL SQLTypeAdapter(const null_type& i); /// \brief Standard assignment operator /// /// \see assign(const SQLTypeAdapter&) for details SQLTypeAdapter& operator =(const SQLTypeAdapter& rhs); /// \brief Replace contents of object with a SQL null /// /// \see assign(const null_type&) for details SQLTypeAdapter& operator =(const null_type& n); /// \brief Returns a const char pointer to the object's raw data operator const char*() const { return data(); } /// \brief Copies another SQLTypeAdapter's data buffer into this /// object. /// /// \param sta Other object to copy /// /// \retval *this /// /// Detaches this object from its internal buffer and attaches /// itself to the other object's buffer, with reference counting /// on each side. If you need a deep copy, call one of the /// assign() overloads taking a C or C++ string instead. SQLTypeAdapter& assign(const SQLTypeAdapter& sta); /// \brief Copies a C string or a raw buffer into this object. /// /// \param pc Pointer to char buffer to copy /// \param len Number of characters to copy; default tells function /// to use the return value of strlen() instead. /// /// \retval *this /// /// If you give the len parameter, this function will treat pc as a /// pointer to an array of char, not as a C string. It only treats /// null characters as special when you leave len at its default. SQLTypeAdapter& assign(const char* pc, int len = -1); /// \brief Replaces contents of object with a SQL null /// /// \param n typically, the MySQL++ global object mysqlpp::null /// /// \retval *this SQLTypeAdapter& assign(const null_type& n); /// \brief Returns the character at a given position within the /// string buffer. /// /// \throw mysqlpp::BadIndex if the internal buffer is not /// initialized (default ctor called, and no subsequent assignment) /// or if there are not at least i + 1 characters in the buffer. /// /// WARNING: The throw-spec is incorrect, but it can't be changed /// until v4, where we can break the ABI. Throw-specs shouldn't be /// relied on anyway. char at(size_type i) const throw(std::out_of_range); /// \brief Compare the internal buffer to the given string /// /// Works just like string::compare(const std::string&). int compare(const SQLTypeAdapter& other) const; /// \brief Compare the internal buffer to the given string /// /// Works just like string::compare(const std::string&). int compare(const std::string& other) const; /// \brief Compare the internal buffer to the given string /// /// Works just like string::compare(size_type, size_type, /// std::string&). int compare(size_type pos, size_type num, std::string& other) const; /// \brief Compare the internal buffer to the given string /// /// Works just like string::compare(const char*). int compare(const char* other) const; /// \brief Compare the internal buffer to the given string /// /// Works just like string::compare(size_type, size_type, /// const char*). int compare(size_type pos, size_type num, const char* other) const; /// \brief Return pointer to raw data buffer const char* data() const; /// \brief Returns true if we were initialized with a data type /// that must be escaped when used in a SQL query bool escape_q() const; /// \brief Return true if buffer's contents represent a SQL /// null. /// /// The buffer's actual content will probably be "NULL" or /// something like it, but in the SQL data type system, a SQL /// null is distinct from a plain string with value "NULL". bool is_null() const { return buffer_->is_null(); } /// \brief Returns true if the internal 'processed' flag is set. /// /// This is an implementation detail of template queries, used to /// prevent repeated processing of values. bool is_processed() const { return is_processed_; } /// \brief Return number of bytes in data buffer size_type length() const; size_type size() const { return length(); } ///< alias for length() /// \brief Returns true if we were initialized with a data type /// that must be quoted when used in a SQL query bool quote_q() const; /// \brief Returns the type ID of the buffer's data /// /// Values from type_info.h. At the moment, these are the same as /// the underlying MySQL C API type IDs, but it's not a good idea /// to count on this remaining the case. int type_id() const; /// \brief Turns on the internal 'is_processed_' flag. /// /// This is an implementation detail of template queries, used to /// prevent repeated processing of values. void set_processed() { is_processed_ = true; } #if !defined(DOXYGEN_IGNORE) // Parallel interface for Null<>-wrapped versions of types we // support above. No need for parallel documentation. SQLTypeAdapter(const Null<std::string>& str, bool processed = false); SQLTypeAdapter(const Null<String>& str, bool processed = false); SQLTypeAdapter(Null<char> c); SQLTypeAdapter(Null< tiny_int<signed char> > i); SQLTypeAdapter(Null< tiny_int<unsigned char> > i); SQLTypeAdapter(Null<short> i); SQLTypeAdapter(Null<unsigned short> i); SQLTypeAdapter(Null<int> i); SQLTypeAdapter(Null<unsigned> i); SQLTypeAdapter(Null<long> i); SQLTypeAdapter(Null<unsigned long> i); SQLTypeAdapter(Null<longlong> i); SQLTypeAdapter(Null<ulonglong> i); SQLTypeAdapter(Null<float> i); SQLTypeAdapter(Null<double> i); SQLTypeAdapter(const Null<Date>& d); SQLTypeAdapter(const Null<DateTime>& dt); SQLTypeAdapter(const Null<Time>& t); SQLTypeAdapter& operator =(const Null<std::string>& str); #endif // !defined(DOXYGEN_IGNORE) private: /// \brief Our internal string buffer RefCountedBuffer buffer_; /// \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 is_processed_; }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_SQL_TYPE_ADAPTER_H) |
Changes to lib/stream2string.h.
1 2 | /// \file stream2string.h /// \brief Declares an adapter that converts something that can be | | | | | | | > | | < < < < | | < | < | | | 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 | /// \file stream2string.h /// \brief Declares an adapter that converts something that can be /// inserted into a C++ stream into a std::string type. /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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_STREAM2STRING_H) #define MYSQLPP_STREAM2STRING_H #include <sstream> #include <string> namespace mysqlpp { /// \brief Converts anything you can insert into a C++ stream to a /// \c std::string via \c std::ostringstream. template <class T> std::string stream2string(const T& object) { std::ostringstream str; str << object; return str.str(); } } // end namespace mysqlpp #endif // !defined(MYSQLPP_STREAM2STRING_H) |
Deleted lib/string_util.cpp.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted lib/string_util.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added lib/tcp_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 | /*********************************************************************** tcp_connection.cpp - Implements the TCPConnection class. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "tcp_connection.h" #include "exceptions.h" #if !defined(MYSQLPP_PLATFORM_WINDOWS) # include <netdb.h> # include <arpa/inet.h> #endif #include <ctype.h> #include <stdlib.h> #include <climits> using namespace std; namespace mysqlpp { bool TCPConnection::connect(const char* addr, const char* db, const char* user, const char* pass) { error_message_.clear(); unsigned int port = 0; string address; if (addr) { address = addr; if (!parse_address(address, port, error_message_)) { return false; } } if (error_message_.empty()) { return Connection::connect(db, address.c_str(), user, pass, port); } else { if (throw_exceptions()) { throw ConnectionFailed(error_message_.c_str()); } else { return false; } } } bool TCPConnection::parse_address(std::string& addr, unsigned int& port, std::string& error) { error.clear(); // Pull off service name or port number, if any string service; if (addr[0] == '[') { // Might be IPv6 address plus port/service in RFC 2732 form. string::size_type pos = addr.find(']'); if ((pos == string::npos) || (addr.find(':', pos + 1) != (pos + 1)) || (addr.find_first_of("[]", pos + 2) != string::npos)) { error = "Malformed IPv6 [address]:service combination"; return false; } // We can separate address from port/service now service = addr.substr(pos + 2); addr = addr.substr(1, pos - 1); // Ensure that address part is empty or has at least two colons if (addr.size() && (((pos = addr.find(':')) == string::npos) || (addr.find(':', pos + 1) == string::npos))) { error = "IPv6 literal needs at least two colons"; return false; } } else { // Can only be IPv4 address, so check for 0-1 colons string::size_type pos = addr.find(':'); if (pos != string::npos) { if (addr.find(':', pos + 1) != string::npos) { error = "IPv4 address:service combo can have only one colon"; return false; } service = addr.substr(pos + 1); addr = addr.substr(0, pos); } } // Turn service into a port number, if it was given. If not, don't // overwrite port because it could have a legal value passed in from // Connection. if (!service.empty()) { if (isdigit(service[0])) { port = atoi(service.c_str()); if ((port < 1) || (port > USHRT_MAX)) { error = "Invalid TCP port number " + service; return false; } } else { servent* pse = getservbyname(service.c_str(), "tcp"); if (pse) { port = ntohs(pse->s_port); } else { error = "Failed to look up TCP service " + service; return false; } } } // Ensure that there are only alphanumeric characters, dots, // dashes and colons in address. Anything else must be an error. for (string::const_iterator it = addr.begin(); it != addr.end(); ++it) { string::value_type c = *it; if (!(isalnum(c) || (c == '.') || (c == '-') || (c == ':'))) { error = "Bad character '"; error += c; error += "' in TCP/IP address"; return false; } } return true; } } // end namespace mysqlpp |
Added lib/tcp_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 | /// \file tcp_connection.h /// \brief Declares the TCPConnection class. /*********************************************************************** Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_TCP_CONNECTION_H) #define MYSQLPP_TCP_CONNECTION_H #include "connection.h" namespace mysqlpp { /// \brief Specialization of \c Connection for TCP/IP /// /// This class just simplifies the connection creation interface of /// \c Connection. It does not add new functionality. class MYSQLPP_EXPORT TCPConnection : public Connection { public: /// \brief Create object without connecting it to the MySQL server. TCPConnection() : Connection() { } /// \brief Create object and connect to database server over TCP/IP /// in one step. /// /// \param addr TCP/IP address of server, in either dotted quad form /// or as a host or domain name; may be followed by a colon and /// a port number or service name to override default port /// \param db name of database to use /// \param user user name to log in under, or 0 to use the user /// name the program is running under /// \param password password to use when logging in /// /// \b BEWARE: These parameters are not in the same order as those /// in the corresponding constructor for Connection. This is a /// feature, not a bug. :) TCPConnection(const char* addr, const char* db = 0, const char* user = 0, const char* password = 0) : Connection() { connect(addr, db, user, password); } /// \brief Establish a new connection using the same parameters as /// an existing connection. /// /// \param other pre-existing connection to clone TCPConnection(const TCPConnection& other) : Connection(other) { } /// \brief Destroy object ~TCPConnection() { } /// \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(const char* addr = 0, const char* db = 0, const char* user = 0, const char* password = 0); /// \brief Break the given TCP/IP address up into a separate address /// and port form /// /// Does some sanity checking on the address. Only intended to /// try and prevent library misuse, not ensure that the address can /// actually be used to contact a server. /// /// It understands the following forms: /// /// - 1.2.3.4 /// /// - a.b.com:89 /// /// - d.e.fr:mysvcname /// /// It also understands IPv6 addresses, but to avoid confusion /// between the colons they use and the colon separating the address /// part from the service/port part, they must be in RFC 2732 form. /// Example: \c [2010:836B:4179::836B:4179]:1234 /// /// \param addr the address and optional port/service combo to check /// on input, and the verified address on successful return /// \param port the port number (resolved from the service name if /// necessary) on successful return /// \param error on false return, reason for failure is placed here /// /// \return false if address fails to pass sanity checks static bool parse_address(std::string& addr, unsigned int& port, std::string& error); private: /// \brief Provide uncallable versions of the parent class ctors we /// don't want to provide so we don't get warnings about hidden /// overloads with some compilers TCPConnection(bool) { } TCPConnection(const char*, const char*, const char*, const char*, unsigned int) { } /// \brief Explicitly override parent class version so we don't get /// complaints about hidden overloads with some compilers bool connect(const char*, const char*, const char*, const char*, unsigned int) { return false; } }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_TCP_CONNECTION_H) |
Changes to lib/tiny_int.h.
1 | /// \file 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 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 | /// \file tiny_int.h /// \brief Declares class for holding a SQL TINYINT /*********************************************************************** Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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_TINY_INT_H) #define MYSQLPP_TINY_INT_H #include "common.h" #include <ostream> namespace mysqlpp { /// \brief Class for holding an SQL \c TINYINT value /// /// 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. For another, if you don't specify /// signedness explicitly, C++ doesn't give a default, so it's signed /// on some platforms, unsigned on others. /// /// The template parameter is intended to allow instantiating it as /// tiny_int<unsigned char> to hold \c TINYINT \c UNSIGNED values. /// There's nothing stopping you from using any other integer type if /// you want to be perverse, but please don't do that. /// /// Several of the functions below accept an \c int argument, but /// internally we store the data as a \c char by default. Beware of /// integer overflows! template <typename VT = signed char> class tiny_int { public: //// Type aliases typedef tiny_int<VT> this_type; ///< alias for this object's type typedef VT value_type; ///< alias for type of internal value /// \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(value_type v) : value_(value_type(v)) { } /// \brief Return truthiness of value operator bool() const { return value_; } /// \brief Return value as an \c int. operator int() const { return static_cast<int>(value_); } /// \brief Return raw data value with no size change operator value_type() const { return value_; } /// \brief Assign a new value to the object. this_type& operator =(int v) { value_ = static_cast<value_type>(v); return *this; } /// \brief Add another value to this object this_type& operator +=(int v) { value_ += static_cast<value_type>(v); return *this; } /// \brief Subtract another value to this object this_type& operator -=(int v) { value_ -= static_cast<value_type>(v); return *this; } /// \brief Multiply this value by another object this_type& operator *=(int v) { value_ *= static_cast<value_type>(v); return *this; } /// \brief Divide this value by another object this_type& operator /=(int v) { value_ /= static_cast<value_type>(v); return *this; } /// \brief Divide this value by another object and store the /// remainder this_type& operator %=(int v) { value_ %= static_cast<value_type>(v); return *this; } /// \brief Bitwise AND this value by another value this_type& operator &=(int v) { value_ &= static_cast<value_type>(v); return *this; } /// \brief Bitwise OR this value by another value this_type& operator |=(int v) { value_ |= static_cast<value_type>(v); return *this; } /// \brief Bitwise XOR this value by another value this_type& operator ^=(int v) { value_ ^= static_cast<value_type>(v); return *this; } /// \brief Shift this value left by \c v positions this_type& operator <<=(int v) { value_ <<= static_cast<value_type>(v); return *this; } /// \brief Shift this value right by \c v positions this_type& operator >>=(int v) { value_ >>= static_cast<value_type>(v); return *this; } /// \brief Add one to this value and return that value this_type& operator ++() { ++value_; return *this; } /// \brief Subtract one from this value and return that value this_type& operator --() { --value_; return *this; } /// \brief Add one to this value and return the previous value this_type operator ++(int) { this_type tmp = value_; ++value_; return tmp; } /// \brief Subtract one from this value and return the previous /// value this_type operator --(int) { this_type tmp = value_; --value_; return tmp; } /// \brief Return this value minus \c i this_type operator -(const this_type& i) const { return value_ - i.value_; } /// \brief Return this value plus \c i this_type operator +(const this_type& i) const { return value_ + i.value_; } /// \brief Return this value multiplied by \c i this_type operator *(const this_type& i) const { return value_ * i.value_; } /// \brief Return this value divided by \c i this_type operator /(const this_type& i) const { return value_ / i.value_; } /// \brief Return the modulus of this value divided by \c i this_type operator %(const this_type& i) const { return value_ % i.value_; } /// \brief Return this value bitwise OR'd by \c i this_type operator |(const this_type& i) const { return value_ | i.value_; } /// \brief Return this value bitwise AND'd by \c i this_type operator &(const this_type& i) const { return value_ & i.value_; } /// \brief Return this value bitwise XOR'd by \c i this_type operator ^(const this_type& i) const { return value_ ^ i.value_; } /// \brief Return this value bitwise shifted left by \c i this_type operator <<(const this_type& i) const { return value_ << i.value_; } /// \brief Return this value bitwise shifted right by \c i this_type operator >>(const this_type& i) const { return value_ >> i.value_; } /// \brief Check for equality bool operator ==(const this_type& i) const { return value_ == i.value_; } /// \brief Check for inequality bool operator !=(const this_type& i) const { return value_ != i.value_; } /// \brief Check that this object is less than another bool operator <(const this_type& i) const { return value_ < i.value_; } /// \brief Check that this object is greater than another bool operator >(const this_type& i) const { return value_ > i.value_; } /// \brief Check this object is less than or equal to another bool operator <=(const this_type& i) const { return value_ <= i.value_; } /// \brief Check this object is greater than or equal to another bool operator >=(const this_type& i) const { return value_ >= i.value_; } private: value_type value_; }; /// \brief Insert a \c tiny_int into a C++ stream template <typename VT> std::ostream& operator <<(std::ostream& os, tiny_int<VT> i) { os << static_cast<int>(i); return os; } } // end namespace mysqlpp #endif |
Added 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | /*********************************************************************** transaction.cpp - Implements the Transaction class. Copyright © 2006-2014 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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; //// ctors ///////////////////////////////////////////////////////////// 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("START TRANSACTION")); if (consistent) { q << " WITH CONSISTENT SNAPSHOT"; } q.execute(); // Setup succeeded, so mark our transaction as not-finished. finished_ = false; } Transaction::Transaction(Connection& conn, IsolationLevel level, IsolationScope scope, bool consistent) : conn_(conn), finished_(true) // don't bother rolling it back if ctor fails { // Set the transaction isolation level and scope as the user wishes Query q(conn_.query("SET ")); if (scope == session) q << "SESSION "; if (scope == global) q << "GLOBAL "; q << "TRANSACTION ISOLATION LEVEL "; switch (level) { case read_uncommitted: q << "READ UNCOMMITTED"; break; case read_committed: q << "READ COMMITTED"; break; case repeatable_read: q << "REPEATABLE READ"; break; case serializable: q << "SERIALIZABLE"; break; } q.execute(); // Begin the transaction set. Note that the above isn't part of // the transaction, on purpose, so that scope == transaction affects // *this* transaction, not the next one. 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() { conn_.query("COMMIT").execute(); finished_ = true; } //// rollback ////////////////////////////////////////////////////////// void Transaction::rollback() { conn_.query("ROLLBACK").execute(); finished_ = true; } |
Added 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 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 | /// \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-2009 by Educational Technology Resources, Inc. and (c) 2008 by AboveNet, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 Transaction isolation levels defined in SQL /// /// These values can be passed to one of the Transaction /// constructors to change the way the database engine protects /// transactions from other DB updates. These values are in order /// of increasing isolation, but decreasing performance. enum IsolationLevel { read_uncommitted, ///< allow "dirty reads" from other transactions read_committed, ///< only read rows committed by other transactions repeatable_read, ///< other transactions do not affect repeated reads in this transaction serializable ///< this transaction prevents writes to any rows it accesses while it runs }; /// \brief Isolation level scopes defined in SQL /// /// These values are only used with one of the Transaction /// constructors, to select which transaction(s) our change to // the isolation scope will affect. enum IsolationScope { this_transaction, ///< change level for this transaction only session, ///< change level for all transactions in this session global ///< change level for all transactions on the DB server }; /// \brief Simple 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 Constructor allowing custom transaction isolation level /// and scope /// /// \param conn The connection we use to manage the transaction set /// \param level Isolation level to use for this transaction /// \param scope Selects the scope of the isolation level change /// \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, IsolationLevel level, IsolationScope scope = this_transaction, 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 }; /// \brief Compile-time substitute for Transaction, which purposely /// does nothing. Use it to instantiate templates that take Transaction /// when you don't want transactions to be used. /// /// This was created for use with InsertPolicy, used by /// Query::insertfrom(). You might use it when your code already /// wraps a given sequence of MySQL++ calls in a transaction and does /// an insertfrom() as part of that. MySQL doesn't support nested /// transactions, so you need to suppress the one insertfrom() would /// normally start. class MYSQLPP_EXPORT NoTransaction { public: /// \brief Constructor NoTransaction(Connection&, bool = false) { } /// \brief Destructor ~NoTransaction() { } /// \brief stub to replace Transaction::commit() void commit() { } /// \brief stub to replace Transaction::rollback() void rollback() { } }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_TRANSACTION_H) |
Changes to lib/type_info.cpp.
1 2 3 | /*********************************************************************** type_info.cpp - Implements the mysql_type_info class. | | | | | | > | > > > | > < < | < | < | | < < | < | | | | | | | > > > > > > | > > > > | > > > > | > > > > | > > > > | > > > > | > > | | > > > > | > > > | > | > | > | > | > | > | > | > | > | | | < < < < < < < < < > | > > > > > > | > > > > > > | > > > > > > | > > > > > > | > > > > > > | > > > > > > | > | > | < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > | > > | > | | < < | < < < < < < > > > | > | | | | | > | | | < < < | < < < < < | < < | < < < < > | | | | | | | < | > | | | < | | | | > > > > > | 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 | /*********************************************************************** type_info.cpp - Implements the mysql_type_info class. Copyright (c) 1998 by Kevin Atkinson, (c) 1999-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.txt 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" #if defined(MYSQLPP_MYSQL_HEADERS_BURIED) # include <mysql/mysql.h> #else # include <mysql.h> #endif #include <string> using namespace std; namespace mysqlpp { // This table maps C++ type information to SQL type information. As you // can see, it's intimately tied in with MySQL's type constants, thus the // name. Unlike in earlier versions of MySQL++, this table is the only // place with such a dependency. Everything else abstracts MySQL's // type system away by bouncing things through this table. // // The second half of the table 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 with tf_default set 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. If you take the subset of all items // marked as default, the typeid() of each item must be unique. const mysql_type_info::sql_type_info mysql_type_info::types[] = { sql_type_info("DECIMAL NOT NULL", typeid(sql_decimal), #if MYSQL_VERSION_ID >= 50001 MYSQL_TYPE_NEWDECIMAL #else MYSQL_TYPE_DECIMAL #endif ), sql_type_info("TINYINT NOT NULL", typeid(sql_tinyint), MYSQL_TYPE_TINY, mysql_ti_sql_type_info::tf_default), sql_type_info("TINYINT UNSIGNED NOT NULL", typeid(sql_tinyint_unsigned), MYSQL_TYPE_TINY, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("SMALLINT NOT NULL", typeid(sql_smallint), MYSQL_TYPE_SHORT, mysql_ti_sql_type_info::tf_default), sql_type_info("SMALLINT UNSIGNED NOT NULL", typeid(sql_smallint_unsigned), MYSQL_TYPE_SHORT, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("INT NOT NULL", typeid(sql_int), MYSQL_TYPE_LONG, mysql_ti_sql_type_info::tf_default), sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), MYSQL_TYPE_LONG, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("FLOAT NOT NULL", typeid(sql_float), MYSQL_TYPE_FLOAT, mysql_ti_sql_type_info::tf_default), sql_type_info("FLOAT UNSIGNED NOT NULL", typeid(sql_float), MYSQL_TYPE_FLOAT, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("DOUBLE NOT NULL", typeid(sql_double), MYSQL_TYPE_DOUBLE, mysql_ti_sql_type_info::tf_default), sql_type_info("DOUBLE UNSIGNED NOT NULL", typeid(sql_double), MYSQL_TYPE_DOUBLE, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("NULL NOT NULL", typeid(void), MYSQL_TYPE_NULL, mysql_ti_sql_type_info::tf_default), sql_type_info("TIMESTAMP NOT NULL", typeid(sql_timestamp), MYSQL_TYPE_TIMESTAMP), sql_type_info("BIGINT NOT NULL", typeid(sql_bigint), MYSQL_TYPE_LONGLONG, mysql_ti_sql_type_info::tf_default), sql_type_info("BIGINT UNSIGNED NOT NULL", typeid(sql_bigint_unsigned), MYSQL_TYPE_LONGLONG, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("MEDIUMINT NOT NULL", typeid(sql_mediumint), MYSQL_TYPE_INT24, mysql_ti_sql_type_info::tf_unsigned), sql_type_info("MEDIUMINT UNSIGNED NOT NULL", typeid(sql_mediumint_unsigned), MYSQL_TYPE_INT24, mysql_ti_sql_type_info::tf_unsigned), sql_type_info("DATE NOT NULL", typeid(sql_date), MYSQL_TYPE_DATE, mysql_ti_sql_type_info::tf_default), sql_type_info("TIME NOT NULL", typeid(sql_time), MYSQL_TYPE_TIME, mysql_ti_sql_type_info::tf_default), sql_type_info("DATETIME NOT NULL", typeid(sql_datetime), MYSQL_TYPE_DATETIME, mysql_ti_sql_type_info::tf_default), sql_type_info("ENUM NOT NULL", typeid(sql_enum), MYSQL_TYPE_ENUM, mysql_ti_sql_type_info::tf_default), sql_type_info("SET NOT NULL", typeid(sql_set), MYSQL_TYPE_SET, mysql_ti_sql_type_info::tf_default), sql_type_info("TINYBLOB NOT NULL", typeid(sql_tinyblob), MYSQL_TYPE_TINY_BLOB), sql_type_info("MEDIUMBLOB NOT NULL", typeid(sql_mediumblob), MYSQL_TYPE_MEDIUM_BLOB), sql_type_info("LONGBLOB NOT NULL", typeid(sql_longblob), MYSQL_TYPE_LONG_BLOB), sql_type_info("BLOB NOT NULL", typeid(sql_blob), MYSQL_TYPE_BLOB, mysql_ti_sql_type_info::tf_default), sql_type_info("VARCHAR NOT NULL", typeid(sql_varchar), MYSQL_TYPE_VAR_STRING, mysql_ti_sql_type_info::tf_default), sql_type_info("CHAR NOT NULL", typeid(sql_char), MYSQL_TYPE_STRING), sql_type_info("DECIMAL NULL", typeid(Null<sql_decimal>), #if MYSQL_VERSION_ID >= 50001 MYSQL_TYPE_NEWDECIMAL #else MYSQL_TYPE_DECIMAL #endif , mysql_ti_sql_type_info::tf_null), sql_type_info("TINYINT NULL", typeid(Null<sql_tinyint>), MYSQL_TYPE_TINY, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("TINYINT UNSIGNED NULL", typeid(Null<sql_tinyint_unsigned>), MYSQL_TYPE_TINY, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("SMALLINT NULL", typeid(Null<sql_smallint>), MYSQL_TYPE_SHORT, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("SMALLINT UNSIGNED NULL", typeid(Null<sql_smallint_unsigned>), MYSQL_TYPE_SHORT, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("INT NULL", typeid(Null<sql_int>), MYSQL_TYPE_LONG, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), MYSQL_TYPE_LONG, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("FLOAT NULL", typeid(Null<sql_float>), MYSQL_TYPE_FLOAT, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("FLOAT UNSIGNED NULL", typeid(Null<sql_float>), MYSQL_TYPE_FLOAT, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("DOUBLE NULL", typeid(Null<sql_double>), MYSQL_TYPE_DOUBLE, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("DOUBLE UNSIGNED NULL", typeid(Null<sql_double>), MYSQL_TYPE_DOUBLE, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("NULL NULL", typeid(Null<void>), MYSQL_TYPE_NULL, mysql_ti_sql_type_info::tf_null), sql_type_info("TIMESTAMP NULL", typeid(Null<sql_timestamp>), MYSQL_TYPE_TIMESTAMP), sql_type_info("BIGINT NULL", typeid(Null<sql_bigint>), MYSQL_TYPE_LONGLONG, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("BIGINT UNSIGNED NULL", typeid(Null<sql_bigint_unsigned>), MYSQL_TYPE_LONGLONG, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("MEDIUMINT NULL", typeid(Null<sql_mediumint>), MYSQL_TYPE_INT24, mysql_ti_sql_type_info::tf_null), sql_type_info("MEDIUMINT UNSIGNED NULL", typeid(Null<sql_mediumint_unsigned>), MYSQL_TYPE_INT24, mysql_ti_sql_type_info::tf_null | mysql_ti_sql_type_info::tf_unsigned), sql_type_info("DATE NULL", typeid(Null<sql_date>), MYSQL_TYPE_DATE, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("TIME NULL", typeid(Null<sql_time>), MYSQL_TYPE_TIME, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("DATETIME NULL", typeid(Null<sql_datetime>), MYSQL_TYPE_DATETIME, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("ENUM NULL", typeid(Null<sql_enum>), MYSQL_TYPE_ENUM, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("SET NULL", typeid(Null<sql_set>), MYSQL_TYPE_SET, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("TINYBLOB NULL", typeid(Null<sql_tinyblob>), MYSQL_TYPE_TINY_BLOB, mysql_ti_sql_type_info::tf_null), sql_type_info("MEDIUMBLOB NULL", typeid(Null<sql_mediumblob>), MYSQL_TYPE_MEDIUM_BLOB, mysql_ti_sql_type_info::tf_null), sql_type_info("LONGBLOB NULL", typeid(Null<sql_longblob>), MYSQL_TYPE_LONG_BLOB, mysql_ti_sql_type_info::tf_null), sql_type_info("BLOB NULL", typeid(Null<sql_blob>), MYSQL_TYPE_BLOB, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("VARCHAR NULL", typeid(Null<sql_varchar>), MYSQL_TYPE_VAR_STRING, mysql_ti_sql_type_info::tf_default | mysql_ti_sql_type_info::tf_null), sql_type_info("CHAR NULL", typeid(Null<sql_char>), MYSQL_TYPE_STRING, mysql_ti_sql_type_info::tf_null) }; const int mysql_type_info::num_types = sizeof(mysql_type_info::types) / sizeof(mysql_type_info::types[0]); const mysql_type_info::sql_type_info_lookup mysql_type_info::lookups(mysql_type_info::types, mysql_type_info::num_types); #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].is_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) { for (unsigned char i = 0; i < num_types; ++i) { if ((types[i].base_type_ == t) && (!_unsigned || types[i].is_unsigned()) && (!_null || types[i].is_null())) { return i; } } return type(MYSQL_TYPE_STRING, false, _null); // punt! } 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_blob) || ti == typeid(sql_tinyblob) || ti == typeid(sql_mediumblob) || ti == typeid(sql_longblob) || ti == typeid(sql_char) || ti == typeid(sql_set); } bool mysql_type_info::escape_q() const { const type_info& ti = base_type().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 |
Changes to lib/type_info.h.
1 2 3 4 5 6 7 | /// \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. /*********************************************************************** | | | | | | | | | | > < < < > > > | > > > > > > > | | > > | > > > > | | | > > > > > | < | > > | | | > > | > > > > | > | > | > | | | < | | | | | | < | < | | | > | < < < < > | < | < | < < < < < < < < < | 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 | /// \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-2001 by MySQL AB, and (c) 2004-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_TYPE_INFO_H) #define MYSQLPP_TYPE_INFO_H #include "common.h" #include "exceptions.h" #include <map> #include <sstream> #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: // For use with flags_ bitset enum { tf_default = 1, tf_null = 2, tf_unsigned = 4 }; 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_( #if MYSQL_VERSION_ID > 40000 MYSQL_TYPE_NULL #else FIELD_TYPE_NULL #endif ), flags_(0) { } mysql_ti_sql_type_info(const char* s, const std::type_info& t, const enum_field_types bt, const unsigned int flags = 0) : sql_name_(s), c_type_(&t), base_type_(bt), flags_(flags) { } bool is_default() const { return flags_ & tf_default; } bool is_null() const { return flags_ & tf_null; } bool is_unsigned() const { return flags_ & tf_unsigned; } const char* sql_name_; const std::type_info* c_type_; const enum_field_types base_type_; const unsigned int flags_; }; 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; typedef std::map<const std::type_info*, unsigned char, type_info_cmp> map_type; mysql_ti_sql_type_info_lookup(const sql_type_info types[], const int size); const unsigned char& operator []( const std::type_info& ti) const { map_type::const_iterator it = map_.find(&ti); if (it != map_.end()) { return it->second; } else { std::ostringstream outs; outs << "Failed to find MySQL C API type ID for " << ti.name(); throw TypeLookupFailed(outs.str()); } } map_type map_; }; #endif // !defined(DOXYGEN_IGNORE) /// \brief SQL field type information /// /// \internal Used within MySQL++ for mapping SQL types to C++ types /// and vice versa. class MYSQLPP_EXPORT mysql_type_info { public: /// \brief Default constructor /// /// This only exists because FieldTypes keeps a vector of these /// objects. You are expected to copy real values into it before /// using it via the copy ctor or one of the assignment operators. /// If you don't, we have arranged a pretty spectacular crash for /// your program. So there. mysql_type_info() : num_(static_cast<unsigned char>(-1)) { } /// \brief Create object from MySQL C API type info /// /// \param t the underlying 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 = false, bool _null = false) : num_(type(t, _unsigned, _null)) { } /// \brief Create object as a copy of another mysql_type_info(const mysql_type_info& t) : 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 another mysql_type_info object to this object mysql_type_info& operator =(const mysql_type_info& t) { num_ = t.num_; return *this; |
︙ | ︙ | |||
190 191 192 193 194 195 196 | 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. | | | | < < < < < < < < < < < < | > > > | | | | | > | > | | < < < < | | > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | 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 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 enum_field_types string_type = #if MYSQL_VERSION_ID > 40000 MYSQL_TYPE_STRING; #else FIELD_TYPE_STRING; #endif 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[]; static const int num_types; 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 Underlying C API type constant /// \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. /// /// While MySQL++ is tied to MySQL, \c t is just an abstraction /// of enum_field_types from mysql_com.h. 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. |
︙ | ︙ | |||
389 390 391 392 393 394 395 | inline bool operator !=(const mysql_type_info& a, const std::type_info& b) { return a.c_type() != b; } } // end namespace mysqlpp | | | 350 351 352 353 354 355 356 357 358 | inline bool operator !=(const mysql_type_info& a, const std::type_info& b) { return a.c_type() != b; } } // end namespace mysqlpp #endif // !defined(MYSQLPP_TYPE_INFO_H) |
Added lib/uds_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 | /*********************************************************************** uds_connection.cpp - Implements the UnixDomainSocketConnection class. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "uds_connection.h" #include "exceptions.h" #if !defined(MYSQLPP_PLATFORM_WINDOWS) # include <unistd.h> # include <sys/stat.h> #endif using namespace std; namespace mysqlpp { static const char* common_complaint = "UnixDomainSocketConnection only works on POSIX systems"; bool UnixDomainSocketConnection::connect(const char* path, const char* db, const char* user, const char* pass) { #if !defined(MYSQLPP_PLATFORM_WINDOWS) if (is_socket(path, &error_message_)) { return Connection::connect(db, path, user, pass); } (void)common_complaint; #else error_message_ = common_complaint; #endif if (throw_exceptions()) { throw ConnectionFailed(error_message_.c_str()); } else { return false; } } bool UnixDomainSocketConnection::is_socket(const char* path, std::string* error) { #if !defined(MYSQLPP_PLATFORM_WINDOWS) if (path) { struct stat fi; if (access(path, F_OK) != 0) { if (error) { *error = path; *error += " does not exist"; } } else if (access(path, R_OK | W_OK) != 0) { if (error) { *error = "Don't have read-write permission for "; *error += path; } } else if (stat(path, &fi) != 0) { if (error) { *error = "Failed to get information for "; *error += path; } } else if (!S_ISSOCK(fi.st_mode)) { if (error) { *error = path; *error += " is not a Unix domain socket"; } } else { // It's a socket, and we have permission to use it if (error) { error->clear(); } return true; } } else #endif if (error) { #if !defined(MYSQLPP_PLATFORM_WINDOWS) *error = "NULL is not a valid Unix domain socket"; #else *error = common_complaint; #endif } return false; } } // end namespace mysqlpp |
Added lib/uds_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 | /// \file uds_connection.h /// \brief Declares the UnixDomainSocketConnection class. /*********************************************************************** Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_UDS_CONNECTION_H) #define MYSQLPP_UDS_CONNECTION_H #include "connection.h" namespace mysqlpp { /// \brief Specialization of \c Connection for Unix domain sockets /// /// This class just simplifies the connection creation interface of /// \c Connection. It does not add new functionality. class UnixDomainSocketConnection : public Connection { public: /// \brief Create object without connecting it to the MySQL server. UnixDomainSocketConnection() : Connection() { } /// \brief Create object and connect to database server over Unix /// domain sockets in one step. /// /// \param path filesystem path to socket /// \param db name of database to use /// \param user user name to log in under, or 0 to use the user /// name the program is running under /// \param password password to use when logging in /// /// \b BEWARE: These parameters are not in the same order as those /// in the corresponding constructor for Connection. This is a /// feature, not a bug. :) UnixDomainSocketConnection(const char* path, const char* db = 0, const char* user = 0, const char* password = 0) : Connection() { connect(path, db, user, password); } /// \brief Establish a new connection using the same parameters as /// an existing connection. /// /// \param other pre-existing connection to clone UnixDomainSocketConnection(const UnixDomainSocketConnection& other) : Connection(other) { } /// \brief Destroy object ~UnixDomainSocketConnection() { } /// \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(const char* path, const char* db = 0, const char* user = 0, const char* password = 0); /// \brief Check that the given path names a Unix domain socket and /// that we have read-write permission for it /// /// \param path the filesystem path to the socket /// \param error on failure, reason is placed here; take default /// if you do not need a reason if it fails /// /// \return false if address fails to pass sanity checks static bool is_socket(const char* path, std::string* error = 0); private: /// \brief Provide uncallable versions of the parent class ctors we /// don't want to provide so we don't get warnings about hidden /// overloads with some compilers UnixDomainSocketConnection(bool) { } UnixDomainSocketConnection(const char*, const char*, const char*, const char*, unsigned int) { } /// \brief Explicitly override parent class version so we don't get /// complaints about hidden overloads with some compilers bool connect(const char*, const char*, const char*, const char*, unsigned int) { return false; } }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_UDS_CONNECTION_H) |
Added lib/utility.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 | /*********************************************************************** utility.cpp - Implements utility functions used within the library. Copyright (c) 2009 by Warren Young. 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 "utility.h" namespace mysqlpp { namespace internal { void str_to_lwr(std::string& s) { std::string::iterator it; for (it = s.begin(); it != s.end(); ++it) { *it = tolower(*it); } } void str_to_lwr(std::string& ls, const char* mcs) { ls.reserve(strlen(mcs)); while (mcs && *mcs) { ls += tolower(*mcs++); } } } // end namespace internal } // end namespace mysqlpp |
Added lib/utility.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 | /// \file utility.h /// \brief Declares utility functions used within MySQL++ /// /// None of this is meant to be used outside the library itself. None /// of this is considered part of the library interface. It is subject /// to change at any time, with no notice. /*********************************************************************** Copyright (c) 2009 by Warren Young. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_UTILITY_H) #define MYSQLPP_UTILITY_H #include "common.h" #include <cctype> #include <cstring> #include <string> namespace mysqlpp { /// \brief Namespace for holding things used only within MySQL++ namespace internal { /// \brief Lowercase a C++ string in place void MYSQLPP_EXPORT str_to_lwr(std::string& s); /// \brief Copy a C string into a C++ string, lowercasing /// it along the way void MYSQLPP_EXPORT str_to_lwr(std::string& ls, const char* mcs); } // end namespace mysqlpp::internal } // end namespace mysqlpp #endif // !defined(MYSQLPP_UTILITY_H) |
Changes to lib/vallist.cpp.
1 2 3 4 5 | /*********************************************************************** 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 | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | /*********************************************************************** 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 |
︙ | ︙ | |||
86 87 88 89 90 91 92 | 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); | | | | | | | | < < < > > > | | | | | < < | | < < | < | | 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 | 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.field_num(s0.c_str())] = true; if (s1.empty()) return; v[c.field_num(s1.c_str())] = true; if (s2.empty()) return; v[c.field_num(s2.c_str())] = true; if (s3.empty()) return; v[c.field_num(s3.c_str())] = true; if (s4.empty()) return; v[c.field_num(s4.c_str())] = true; if (s5.empty()) return; v[c.field_num(s5.c_str())] = true; if (s6.empty()) return; v[c.field_num(s6.c_str())] = true; if (s7.empty()) return; v[c.field_num(s7.c_str())] = true; if (s8.empty()) return; v[c.field_num(s8.c_str())] = true; if (s9.empty()) return; v[c.field_num(s9.c_str())] = true; if (sa.empty()) return; v[c.field_num(sa.c_str())] = true; if (sb.empty()) return; v[c.field_num(sb.c_str())] = true; if (sc.empty()) return; v[c.field_num(sc.c_str())] = 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 |
Changes to lib/vallist.h.
︙ | ︙ | |||
21 22 23 24 25 26 27 | 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 ***********************************************************************/ | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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_VALLIST_H) #define MYSQLPP_VALLIST_H #include "manip.h" #include <string> #include <vector> |
︙ | ︙ | |||
64 65 66 67 68 69 70 | 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 | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 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* delim; /// \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 |
︙ | ︙ | |||
88 89 90 91 92 93 94 | /// 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), | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /// 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), delim(d), equl(e), manip(m) { } }; |
︙ | ︙ | |||
123 124 125 126 127 128 129 | 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 | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | 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* delim; /// \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 |
︙ | ︙ | |||
151 152 153 154 155 156 157 | /// 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), | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | /// 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), delim(d), equl(e), manip(m) { } }; |
︙ | ︙ | |||
186 187 188 189 190 191 192 | 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 | | | | 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 | 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* delim; /// \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), delim(d), manip(m) { } }; /// \brief Same as value_list_ba, plus the option to have some elements |
︙ | ︙ | |||
230 231 232 233 234 235 236 | /// \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 | | | | | 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 | /// \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* delim; /// \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), delim(d), manip(m) { } }; /// \brief Inserts an equal_list_ba into an std::ostream. |
︙ | ︙ | |||
277 278 279 280 281 282 283 | 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; } | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | 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.delim; } return o; } /// \brief Same as operator<< for equal_list_ba, plus the option to |
︙ | ︙ | |||
305 306 307 308 309 310 311 | 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]) { | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | 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.delim; } } return o; } |
︙ | ︙ | |||
333 334 335 336 337 338 339 | typename Seq::const_iterator i = cl.list->begin(); while (1) { o << cl.manip << *i; if (++i == cl.list->end()) { break; } | | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | typename Seq::const_iterator i = cl.list->begin(); while (1) { o << cl.manip << *i; if (++i == cl.list->end()) { break; } o << cl.delim; } return o; } /// \brief Same as operator<< for value_list_ba, plus the option to |
︙ | ︙ | |||
357 358 359 360 361 362 363 | int k = 0; while (1) { if (cl.fields[k++]) { o << cl.manip << *i; } if (++i == cl.list->end()) { | | | | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | 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.delim; } } return o; } |
︙ | ︙ | |||
433 434 435 436 437 438 439 | /// /// \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> | | | | 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 | /// /// \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) /// |
︙ | ︙ | |||
679 680 681 682 683 684 685 | t9, ta, tb, tc); return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb, ",", " = ", do_nothing); } } // end namespace mysqlpp | | | 679 680 681 682 683 684 685 686 | t9, ta, tb, tc); return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb, ",", " = ", do_nothing); } } // end namespace mysqlpp #endif // !defined(MYSQLPP_VALLIST_H) |
Added lib/wnp_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 | /*********************************************************************** wnp_connection.cpp - Implements the WindowsNamedPipeConnection class. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "wnp_connection.h" #include "exceptions.h" using namespace std; namespace mysqlpp { static const char* common_complaint = "WindowsNamedPipeConnection only works on Windows"; bool WindowsNamedPipeConnection::connect(const char* db, const char* user, const char* pass) { #if defined(MYSQLPP_PLATFORM_WINDOWS) return Connection::connect(db, ".", user, pass); #else (void)db; (void)user; (void)pass; error_message_ = common_complaint; if (throw_exceptions()) { throw ConnectionFailed(error_message_.c_str()); } else { return false; } #endif } bool WindowsNamedPipeConnection::is_wnp(const char* server) { #if defined(MYSQLPP_PLATFORM_WINDOWS) return server && (strcmp(server, ".") == 0); #else (void)server; return false; #endif } } // end namespace mysqlpp |
Added lib/wnp_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 | /// \file wnp_connection.h /// \brief Declares the WindowsNamedPipeConnection class. /*********************************************************************** Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_WNP_CONNECTION_H) #define MYSQLPP_WNP_CONNECTION_H #include "connection.h" namespace mysqlpp { /// \brief Specialization of \c Connection for Windows named pipes /// /// This class just simplifies the connection creation interface of /// \c Connection. It does not add new functionality. class MYSQLPP_EXPORT WindowsNamedPipeConnection : public Connection { public: /// \brief Create object without connecting it to the MySQL server. WindowsNamedPipeConnection() : Connection() { } /// \brief Create object and connect to database server over Windows /// named pipes in one step. /// /// \param db name of database to use /// \param user user name to log in under, or 0 to use the user /// name the program is running under /// \param password password to use when logging in WindowsNamedPipeConnection(const char* db, const char* user = 0, const char* password = 0) : Connection() { connect(db, user, password); } /// \brief Establish a new connection using the same parameters as /// an existing connection. /// /// \param other pre-existing connection to clone WindowsNamedPipeConnection(const WindowsNamedPipeConnection& other) : Connection(other) { } /// \brief Destroy object ~WindowsNamedPipeConnection() { } /// \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(const char* db = 0, const char* user = 0, const char* password = 0); /// \brief Check that given string denotes a Windows named pipe /// connection to MySQL /// /// \param server the server address /// /// \return false if server address does not denote a Windows /// named pipe connection, or we are not running on Windows static bool is_wnp(const char* server); private: /// \brief Provide uncallable versions of the parent class ctors we /// don't want to provide so we don't get warnings about hidden /// overloads with some compilers WindowsNamedPipeConnection(bool) { } WindowsNamedPipeConnection(const char*, const char*, const char*, const char*, unsigned int) { } /// \brief Explicitly override parent class version so we don't get /// complaints about hidden overloads with some compilers bool connect(const char*, const char*, const char*, const char*, unsigned int) { return false; } }; } // end namespace mysqlpp #endif // !defined(MYSQLPP_WNP_CONNECTION_H) |
Deleted makemake.bat.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted makemake.sh.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 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 | <?xml version="1.0"?> <makefile> <requires version="0.2.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="STABLEABI">3.1.0</set> <set var="OLDABIDIR">../$(STABLEABI)/abi_dumps/mysqlpp</set> <set var="NEWABIDIR">./abi_dumps/mysqlpp</set> <set var="PLATFORM_WINDOWS_NATIVE">no</set> <set var="THREAD_TYPE">single</set> <if cond="FORMAT in ['msvs2003prj', 'msvs2005prj', 'msvs2008prj', 'mingw']"> <set var="PLATFORM_WINDOWS_NATIVE">yes</set> <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="MYSQL_WIN_DIR"> C:\Program Files\MySQL\MySQL Connector C 6.1 </set> <set var="DEBUGINFO"> <if cond="BUILD=='debug'">on</if> <if cond="BUILD=='release'">off</if> </set> <set var="OPTIMIZE_FLAG"> <if cond="BUILD=='debug'">off</if> <if cond="BUILD=='release'">speed</if> </set> <!-- This convoluted syntax adds "_d" to the end of library and DLL file names for VC++ and Xcode, in debug mode only. --> <set var="DEBUG_SUFFIX"/> <set var="DEBUG_SUFFIX"> <if cond="FORMAT in ['msvs2003prj', 'msvs2005prj', 'msvs2008prj', 'xcode2'] and BUILD=='debug'">_d</if> </set> <set var="BUILDDOCS">yes</set> <set var="BUILDEXAMPLES">yes</set> <set var="BUILDLIBRARY">yes</set> <set var="BUILDTEST">yes</set> <set var="HEADER_DIR">$(PREFIX)/include/mysql++</set> <if cond="FORMAT in ['msvs2003prj', 'msvs2005prj', 'msvs2008prj']"> <set-srcdir>..</set-srcdir> </if> <if cond="BUILDLIBRARY=='yes'"> <dll id="mysqlpp"> <dllname>mysqlpp$(DEBUG_SUFFIX)</dllname> <libname>mysqlpp$(DEBUG_SUFFIX)</libname> <so_version>3.2.3</so_version> <sources> lib/beemutex.cpp lib/cmdline.cpp lib/connection.cpp lib/cpool.cpp lib/datetime.cpp lib/dbdriver.cpp lib/field_names.cpp lib/field_types.cpp lib/manip.cpp lib/myset.cpp lib/mysql++.cpp lib/mystring.cpp lib/null.cpp lib/options.cpp lib/qparms.cpp lib/query.cpp lib/result.cpp lib/row.cpp lib/scopedconnection.cpp lib/sql_buffer.cpp lib/sqlstream.cpp lib/ssqls2.cpp lib/stadapter.cpp lib/tcp_connection.cpp lib/transaction.cpp lib/type_info.cpp lib/uds_connection.cpp lib/utility.cpp lib/vallist.cpp lib/wnp_connection.cpp </sources> <debug-info>$(DEBUGINFO)</debug-info> <optimize>$(OPTIMIZE_FLAG)</optimize> <threading>$(THREAD_TYPE)</threading> <cxx-rtti>on</cxx-rtti> <cxx-exceptions>on</cxx-exceptions> <install-to>$(LIBDIR)</install-to> <if cond="PLATFORM_WINDOWS_NATIVE=='yes'"> <define>UNICODE</define> <define>_UNICODE</define> <sys-lib>wsock32</sys-lib> </if> <if cond="FORMAT in ['msvs2003prj', 'msvs2005prj', 'msvs2008prj']"> <define>MYSQLPP_MAKING_DLL</define> <define>HAVE_MYSQL_SSL_SET</define> <include>$(MYSQL_WIN_DIR)\include</include> <lib-path>$(MYSQL_WIN_DIR)\lib</lib-path> <sys-lib>libmysql</sys-lib> </if> <if cond="FORMAT=='mingw'"> <define>MYSQLPP_NO_DLL</define> <define>HAVE_MYSQL_SSL_SET</define> <include>"$(MYSQL_WIN_DIR)\include"</include> <ldflags>-Wl,--enable-stdcall-fixup</ldflags> <lib-path>"$(MYSQL_WIN_DIR)\lib"</lib-path> <sys-lib>mysql</sys-lib> </if> <if cond="FORMAT=='autoconf'"> <depends>lib/ssqls.h</depends> <depends>lib/querydef.h</depends> <cxxflags>@PTHREAD_CFLAGS@</cxxflags> <include>.</include> <include>@MYSQL_C_INC_DIR@</include> <ldflags>-L@MYSQL_C_LIB_DIR@</ldflags> <ldflags>-l@MYSQL_C_LIB_NAME@ @PTHREAD_LIBS@ @MYSQLPP_EXTRA_LIBS@</ldflags> </if> <if cond="FORMAT=='xcode2'"> <define>HAVE_POSIX_GETOPT</define> <define>MYSQLPP_XCODE</define> <include>/usr/local/mysql/include</include> <ldflags>-lmysqlclient</ldflags> <!-- Assume C API files came from MySQL.com DMGs, not source tarball, Fink, etc., inferring preference from use of Xcode. --> <lib-path>/usr/local/mysql/lib</lib-path> </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 built executables --> <template id="programs"> <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> <optimize>$(OPTIMIZE_FLAG)</optimize> <if cond="FORMAT in ['autoconf', 'gnu', 'mingw', 'xcode2']"> <include>lib</include> <include>@MYSQL_C_INC_DIR@</include> <lib-path>@MYSQL_C_LIB_DIR@</lib-path> <lib-path>.</lib-path> </if> <if cond="FORMAT in ['msvs2003prj', 'msvs2005prj', 'msvs2008prj']"> <include>../lib</include> </if> <if cond="FORMAT=='xcode2'"> <define>HAVE_POSIX_GETOPT</define> <define>MYSQLPP_XCODE</define> <include>/usr/local/mysql/include</include> <ldflags>-lmysqlclient</ldflags> <lib-path>/usr/local/mysql/lib</lib-path> </if> <if cond="PLATFORM_WINDOWS_NATIVE=='yes'"> <define>UNICODE</define> <define>_UNICODE</define> </if> <if cond="FORMAT=='autoconf'"> <cxxflags>@PTHREAD_CFLAGS@</cxxflags> <ldflags>-l@MYSQL_C_LIB_NAME@ @PTHREAD_LIBS@ @MYSQLPP_EXTRA_LIBS@</ldflags> <warnings>max</warnings> <sys-lib>mysqlpp</sys-lib> </if> <if cond="FORMAT=='mingw'"> <define>MYSQLPP_NO_DLL</define> <ldflags> -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-stdcall-fixup </ldflags> <include>"$(MYSQL_WIN_DIR)\include"</include> <lib-path>"$(MYSQL_WIN_DIR)\lib"</lib-path> <sys-lib>mysql</sys-lib> <sys-lib>mysqlpp$(DEBUG_SUFFIX)</sys-lib> </if> <if cond="FORMAT in ['msvs2003prj', 'msvs2005prj', 'msvs2008prj']"> <lib-path>$(BUILD)</lib-path> <include>$(MYSQL_WIN_DIR)\include</include> <lib-path>$(MYSQL_WIN_DIR)\lib</lib-path> <sys-lib>mysqlpp$(DEBUG_SUFFIX)</sys-lib> <sys-lib>libmysql</sys-lib> </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> <if cond="FORMAT=='xcode2'"> <include>/usr/local/mysql/include</include> <sys-lib>mysqlclient</sys-lib> <sys-lib>mysqlpp$(DEBUG_SUFFIX)</sys-lib> </if> </template> <if cond="BUILDLIBRARY=='yes'"> <!-- SSQLS v2 parser convenience library --> <lib id="ssqls2parse" template="programs"> <depends>mysqlpp</depends> <libname>mysqlpp_ssqls2parse</libname> <sources>ssx/parsev2.cpp</sources> <include>.</include> </lib> <!-- Build rules for ssqlsxlat tool --> <exe id="ssqlsxlat" template="programs"> <sources>ssx/genv2.cpp</sources> <sources>ssx/main.cpp</sources> <depends>ssqls2parse</depends> <sys-lib>mysqlpp_ssqls2parse</sys-lib> <sys-lib>mysqlpp</sys-lib> </exe> </if> <!-- Define library testing programs' output targets, if enabled --> <if cond="BUILDTEST=='yes'"> <exe id="test_array_index" template="programs"> <sources>test/array_index.cpp</sources> </exe> <exe id="test_cpool" template="programs"> <sources>test/cpool.cpp</sources> </exe> <exe id="test_datetime" template="programs"> <sources>test/datetime.cpp</sources> </exe> <exe id="test_inttypes" template="programs"> <sources>test/inttypes.cpp</sources> </exe> <exe id="test_insertpolicy" template="programs"> <sources>test/insertpolicy.cpp</sources> </exe> <exe id="test_manip" template="programs"> <sources>test/manip.cpp</sources> </exe> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile this --> <exe id="test_null_comparison" template="programs"> <sources>test/null_comparison.cpp</sources> </exe> </if> <exe id="test_query_copy" template="programs"> <sources>test/query_copy.cpp</sources> </exe> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile this --> <exe id="test_qssqls" template="programs"> <sources>test/qssqls.cpp</sources> </exe> </if> <exe id="test_qstream" template="programs"> <sources>test/qstream.cpp</sources> </exe> <exe id="test_sqlstream" template="programs"> <sources>test/sqlstream.cpp</sources> </exe> <if cond="BUILDLIBRARY=='yes'"> <exe id="test_ssqls2" template="programs"> <sources>test/ssqls2.cpp</sources> <depends>ssqls2parse</depends> <sys-lib>mysqlpp_ssqls2parse</sys-lib> <sys-lib>mysqlpp</sys-lib> </exe> </if> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile this --> <exe id="test_string" template="programs"> <sources>test/string.cpp</sources> </exe> </if> <exe id="test_tcp" template="programs"> <sources>test/tcp.cpp</sources> </exe> <exe id="test_uds" template="programs"> <sources>test/uds.cpp</sources> </exe> <exe id="test_wnp" template="programs"> <sources>test/wnp.cpp</sources> </exe> </if> <!-- build library test programs --> <!-- Define example programs' output targets, if enabled --> <if cond="BUILDEXAMPLES=='yes'"> <!-- Options specific to examples that depend on libexcommon --> <template id="libexcommon-user"> <depends>excommon</depends> <sys-lib>mysqlpp_excommon</sys-lib> </template> <!-- Convenience library of routines used by most examples --> <lib id="excommon" template="programs"> <libname>mysqlpp_excommon</libname> <sources>examples/printdata.cpp</sources> </lib> <!-- The examples themselves --> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile current SSQLS code --> <exe id="cgi_jpeg" template="libexcommon-user,programs"> <sources>examples/cgi_jpeg.cpp</sources> </exe> </if> <exe id="cpool" template="libexcommon-user,programs"> <sources>examples/cpool.cpp</sources> </exe> <exe id="dbinfo" template="libexcommon-user,programs"> <sources>examples/dbinfo.cpp</sources> </exe> <exe id="deadlock" template="libexcommon-user,programs"> <sources>examples/deadlock.cpp</sources> </exe> <exe id="fieldinf" template="libexcommon-user,programs"> <sources>examples/fieldinf.cpp</sources> </exe> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile current SSQLS code --> <exe id="for_each" template="libexcommon-user,programs"> <sources>examples/for_each.cpp</sources> </exe> </if> <exe id="load_jpeg" template="libexcommon-user,programs"> <sources>examples/load_jpeg.cpp</sources> </exe> <exe id="multiquery" template="libexcommon-user,programs"> <sources>examples/multiquery.cpp</sources> </exe> <exe id="resetdb" template="libexcommon-user,programs"> <sources>examples/resetdb.cpp</sources> </exe> <exe id="simple1" template="libexcommon-user,programs"> <sources>examples/simple1.cpp</sources> </exe> <exe id="simple2" template="libexcommon-user,programs"> <sources>examples/simple2.cpp</sources> </exe> <exe id="simple3" template="libexcommon-user,programs"> <sources>examples/simple3.cpp</sources> </exe> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile current SSQLS code --> <exe id="ssqls1" template="libexcommon-user,programs"> <sources>examples/ssqls1.cpp</sources> </exe> <exe id="ssqls2" template="libexcommon-user,programs"> <sources>examples/ssqls2.cpp</sources> </exe> <exe id="ssqls3" template="libexcommon-user,programs"> <sources>examples/ssqls3.cpp</sources> </exe> <exe id="ssqls4" template="libexcommon-user,programs"> <sources>examples/ssqls4.cpp</sources> </exe> <exe id="ssqls5" template="libexcommon-user,programs"> <sources>examples/ssqls5.cpp</sources> </exe> <exe id="ssqls6" template="libexcommon-user,programs">$ <sources>examples/ssqls6.cpp</sources> </exe>$ <exe id="store_if" template="libexcommon-user,programs"> <sources>examples/store_if.cpp</sources> </exe> </if> <exe id="tquery1" template="libexcommon-user,programs"> <sources>examples/tquery1.cpp</sources> </exe> <exe id="tquery2" template="libexcommon-user,programs"> <sources>examples/tquery2.cpp</sources> </exe> <exe id="tquery3" template="libexcommon-user,programs"> <sources>examples/tquery3.cpp</sources> </exe> <exe id="tquery4" template="libexcommon-user,programs"> <sources>examples/tquery4.cpp</sources> </exe> <if cond="FORMAT!='msvs2003prj'"> <!-- VC++ 2003 can't compile current SSQLS code --> <exe id="transaction" template="libexcommon-user,programs"> <sources>examples/transaction.cpp</sources> </exe> </if> </if> <!-- build examples --> <if cond="FORMAT=='autoconf'"> <set var="PKGNAME">@PACKAGE_NAME@-@PACKAGE_VERSION@</set> <modify-target target="clean"> <command> rm -rf doc/latex doc/pdf ; \ cd doc/html/refman ; \ rm -f doxygen.css [a-z]*.{dot,html,map,md5,png} </command> </modify-target> <modify-target target="uninstall"> <command> -rmdir $(HEADER_DIR) </command> <command> rm -f $(DESTDIR)$(libdir)/$(DLLPREFIX)mysqlpp.$(SO_SUFFIX) </command> </modify-target> <action id="Makefile"> <depends-on-file>configure.ac</depends-on-file> <depends-on-file>install.hta.in</depends-on-file> <depends-on-file>mysql++.bkl</depends-on-file> <depends-on-file>mysql++.spec.in</depends-on-file> <depends-on-file>doc/userman/userman.dbx.in</depends-on-file> <depends-on-file>lib/Doxyfile.in</depends-on-file> <depends-on-file>lib/mysql++.h.in</depends-on-file> <depends-on-file>ssx/Doxyfile.in</depends-on-file> <command>bakefile_gen</command> <command>./config.status</command> </action> <action id="lib/ssqls.h"> <command>cd lib ; ./ssqls.pl</command> <depends-on-file>lib/ssqls.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 --recurse=yes .</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> cd lib ; doxygen > /dev/null </command> </action> <action id="doc/html/refman/ssx/index.html"> <depends-on-file>ssx/Doxyfile</depends-on-file> <depends-on-file>ssx/*.cpp</depends-on-file> <depends-on-file>ssx/*.h</depends-on-file> <command> cd ssx ; doxygen > /dev/null </command> </action> <action id="doc/html/userman/index.html"> <depends-on-file>doc/userman/*.dbx</depends-on-file> <depends-on-file>doc/userman/userman.dbx.in</depends-on-file> <command> cd doc/userman ; make html pdf </command> </action> <action id="doc"> <depends>doc/html/refman/index.html</depends> <depends>doc/html/refman/ssx/index.html</depends> <depends>doc/html/userman/index.html</depends> </action> <action id="@PACKAGE_NAME@-@PACKAGE_VERSION@"> <!-- Set up package directory --> <command> for d in config doc/html/refman doc/html/userman \ doc/refman doc/userman examples lib ssx test ; \ do \ mkdir -p $(PKGNAME)/$(DDD) ; \ done </command> <!-- Copy files into package directory --> <!-- top directory --> <command> cp -RL *.bat *.in *.txt abi.xml aclocal.m4 Bakefiles.bkgen \ bootstrap ChangeLog cleanmf config.guess config.h config.sub \ configure* dtest exrun install* Makefile.* mysql++.* osver \ Wishlist $(PKGNAME) </command> <!-- VC++ project file subdirs --> <command> for d in vc200? ; do \ mkdir -p $(PKGNAME)/$(DDD) ; \ cp $(DDD)/*.sln $(DDD)/*.vcproj $(PKGNAME)/$(DDD) ; \ done </command> <!-- config subdir --> <command>cp config/*.m4 $(PKGNAME)/config</command> <!-- doc subdir --> <if cond="BUILDDOCS=='yes'"> <command> cp -RL doc/README* doc/pdf doc/ssqls-pretty $(PKGNAME)/doc </command> <command> for f in fo2pdf LICENSE.txt Makefile Makefile.hello.* mktxt README.txt \*.dbx \*.in \*.mod \*.txt \*.xsl ; \ do \ cp doc/userman/$(DDF) $(PKGNAME)/doc/userman ; \ done </command> <command> find doc \( -name *.css -o -name *.html \) -exec install {} $(PKGNAME)/{} \; </command> <command> cp doc/html/refman/*.png $(PKGNAME)/doc/html/refman </command> </if> <if cond="BUILDDOCS!='yes'"> <!-- We have to copy this file even though we don't build the docs to make configure happy, because it wants to update the version number. --> <command> cp doc/userman/userman.dbx.in $(PKGNAME)/doc/userman </command> </if> <!-- examples subdir --> <command> cp examples/*.{cpp,h,jpg,txt} $(PKGNAME)/examples </command> <command> for d in mfc wforms ; \ do \ mkdir -p $(PKGNAME)/examples/vstudio/$(DDD) ; \ cp examples/vstudio/$(DDD)/* $(PKGNAME)/examples/vstudio/$(DDD) ; \ done </command> <!-- lib subdir --> <command> cp lib/*.cpp lib/*.h lib/*.in lib/*.pl $(PKGNAME)/lib </command> <!-- test subdir --> <command> cp test/*.cpp $(PKGNAME)/test </command> <!-- ssx subdir --> <command> cp ssx/*.cpp ssx/*.h ssx/*.in $(PKGNAME)/ssx </command> <!-- re-bootstrap it to get a standard configuration --> <command>cd $(PKGNAME) ; ./bootstrap nodoc nomaint</command> <command>rm -f $(PKGNAME)/Makefile</command> <command>rm -f $(PKGNAME)/config.log</command> <command>rm -f $(PKGNAME)/config.status</command> <command>rm -fr $(PKGNAME)/autom4te.cache</command> </action> <action id="abicheck"> <command> <![CDATA[ abi-compliance-checker -lib mysqlpp -dump abi.xml abi-compliance-checker -lib mysqlpp \ -old $(OLDABIDIR)/mysqlpp_$(STABLEABI).abi.tar.gz \ -new $(NEWABIDIR)/mysqlpp_@PACKAGE_VERSION@.abi.tar.gz mv compat_reports/mysqlpp/*/compat_report.html ~/Desktop find compat_reports -empty -delete ]]> </command> </action> <action id="dist"> <depends>doc</depends> <depends>$(PKGNAME)</depends> <command>tar czf $(PKGNAME).tar.gz $(PKGNAME)</command> <command>rm -rf $(PKGNAME)</command> </action> <action id="rpm-prep"> <if cond="BUILDDOCS=='yes'"> <depends>doc</depends> </if> <depends>dist</depends> <command>cp $(PKGNAME).tar.gz ~/rpmbuild/SOURCES</command> <command>cd ~/rpmbuild/SPECS</command> </action> <action id="rpm"> <depends>rpm-prep</depends> <command>rpmbuild -ba mysql++.spec</command> </action> <action id="srpm"> <depends>rpm-prep</depends> <command>rpmbuild -bs mysql++.spec</command> </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> |
Changes to 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | # Copyright 1999-2008 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: /var/cvsroot/gentoo-x86/dev-db/mysql++/mysql++-2.3.2.ebuild,v 1.3 2008/04/21 03:00:49 dirtyepic Exp $ inherit eutils DESCRIPTION="C++ API interface to the MySQL database" HOMEPAGE="http://tangentsoft.net/mysql++/" SRC_URI="http://www.tangentsoft.net/mysql++/releases/${P}.tar.gz" LICENSE="LGPL-2" SLOT="0" KEYWORDS="~alpha ~amd64 ~hppa ~mips ~ppc ~sparc ~x86" IUSE="" DEPEND=">=sys-devel/gcc-3" RDEPEND="${DEPEND} >=virtual/mysql-4.0" src_unpack() { unpack ${A} cd "${S}" epatch "${FILESDIR}"/${P}-gcc-4.3.patch for i in "${S}"/lib/*.h ; do sed -i \ -e '/#include </s,mysql.h,mysql/mysql.h,g' \ -e '/#include </s,mysql_version.h,mysql/mysql_version.h,g' \ "${i}" || die "Failed to sed ${i} for fixing MySQL includes" done } src_compile() { local myconf # we want C++ exceptions turned on myconf="--enable-exceptions" # give threads a try myconf="${myconf} --enable-thread-check" # 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="${CXXFLAGS}" \ econf ${myconf} || die "econf failed" emake || die "unable to make" } src_install() { emake DESTDIR="${D}" install || die # install the docs and HTML pages dodoc README* CREDITS ChangeLog HACKERS Wishlist dodoc doc/* cp -ra doc/html "${D}"/usr/share/doc/${PF}/html prepalldocs } |
Changes to 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 | 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-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 # Fakery for nodoc case if [ ! -e doc/README-devel-RPM.txt ] then touch doc/README-devel-RPM.txt touch doc/README-doc-RPM.txt touch doc/README-manuals-RPM.txt %{__mkdir_p} doc/html doc/pdf fi %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/ %{__install} -m644 config.h doc/examples/ sed -i -e s@../config.h@config.h@ doc/examples/threads.h # 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@@' \ -e '/^all:/s/test_[a-z,_]* //g' \ 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.txt CREDITS.txt LICENSE.txt README.txt %{_libdir}/libmysqlpp.so.* %files devel %defattr(-,root,root,-) %doc doc/examples doc/README-devel-RPM.txt README-examples.txt Wishlist %{_includedir}/mysql++ %{_libdir}/libmysqlpp.so %files manuals %defattr(-,root,root,-) %doc doc/html doc/pdf doc/README-manuals-RPM.txt %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 |
︙ | ︙ |
Added 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 |
Added rebake.bat.
> > | 1 2 | @echo on bakefile_gen %* |
Added ssx/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 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 | # Doxyfile 1.8.5 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single 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. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "MySQL++ SSQLS v2 Translator" # 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@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. 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 causes # performance problems for the file system. # The default value is: NO. 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. # Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- # Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, # Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES 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. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES 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. # The default value is: YES. 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 and 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. # The default value is: NO. 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. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES 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 # The default value is: YES. FULL_PATH_NAMES = NO # 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. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. 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 list of 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. # The default value is: NO. 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-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_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 behavior. 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 behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. 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. # The default value is: NO. 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. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act 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 = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # 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. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # 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); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # 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. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES 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. # The default value is: YES. SUBGROUPING = NO # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # 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 respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. 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. Does not have any effect # for Java sources. # The default value is: YES. 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 only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO 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. # The default value is: NO. HIDE_UNDOC_MEMBERS = YES # 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 these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. 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 these declarations will be # included in the documentation. # The default value is: NO. 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 these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. 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 then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. 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. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES 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. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = 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 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. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = 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. # The default value is: YES. 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. # The default value is: YES. 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. # The default value is: YES. 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. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if <section_label> ... \endif and \cond <section_label> # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have 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 value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. 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. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # 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. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. Do not use file names with spaces, bibtex cannot handle them. See # also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag 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. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag 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. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. 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) # The default value is: $file:$line: $text. 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 standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is 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. # Note: If this tag is empty the current directory is searched. 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. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. 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 patterns (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, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # 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. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. 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 # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */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. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be 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. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. 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 information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # 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 that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES 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 documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = 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. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES 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. # See also: Section \class. # The default value is: YES. 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. # The default value is: YES. ALPHABETICAL_INDEX = NO # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. 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 a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. 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. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html/refman/ssx # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = ../doc/html/refman/_header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. 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 left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # 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. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # 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. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # 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). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # 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. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value 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 # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # 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. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use <access key> + S # (what the <access key> is depends on the OS and browser, but it is typically # <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down # key> to jump into the search results window, the results can be navigated # using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel # the search. The filter options can be selected when the cursor is inside the # search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> # to select a filter and <Enter> or <escape> to activate or cancel the filter # option. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There # are two flavours of web server based searching depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. See # the section "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # # Doxygen ships with an example indexer ( doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # # Doxygen ships with an example indexer ( doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. # The default file is: searchdata.xml. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of # to a relative location where the documentation can be found. The format is: # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO # 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. # The default directory is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # # Note that when enabling USE_PDFLATEX this option is only used for generating # bitmaps for formulas in the HTML output, but not in the Makefile that is # written to the output directory. # The default file is: latex. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. 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. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. 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 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x # 14 inches) and executive (7.25 x 10.5 inches). # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # that should be included in the LaTeX output. To get the times font for # instance you can specify # EXTRA_PACKAGES=times # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. 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. See # section "Doxygen usage" for information on how to let doxygen write the # default header to a separate file. # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, # $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will # replace them by respectively the title of the page, the current date and time, # only the current date, the version number of doxygen, the project name (see # PROJECT_NAME), or the project number (see PROJECT_NUMBER). # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last # chapter. If it is left blank doxygen will generate a standard footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). 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. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. PDF_HYPERLINKS = NO # If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # the PDF file directly from the LaTeX files. Set this option to YES to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. 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. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BATCHMODE = NO # If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the # index chapters (such as File Index, Compound Index, etc.) in the output. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HIDE_INDICES = NO # If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source # code with syntax highlighting in the LaTeX output. # # Note that which sources are shown also depends on other settings such as # SOURCE_BROWSER. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # http://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # 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 too pretty with other RTF # readers/editors. # The default value is: NO. 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. # The default directory is: rtf. # This tag requires that the tag GENERATE_RTF is set to YES. 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. # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. 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 some other Word compatible readers that support those # fields. # # Note: WordPad (write) and others do not support links. # The default value is: NO. # This tag requires that the tag GENERATE_RTF is set to YES. 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. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is # similar to doxygen's config file. A template extensions file can be generated # using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES doxygen will generate man pages for # classes and files. # The default value is: NO. 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. A directory man3 will be created inside the directory specified by # MAN_OUTPUT. # The default directory is: man. # This tag requires that the tag GENERATE_MAN is set to YES. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to the generated # man pages. In case the manual section does not start with a number, the number # 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is # optional. # The default value is: .3. # This tag requires that the tag GENERATE_MAN is set to YES. 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 value is: NO. # This tag requires that the tag GENERATE_MAN is set to YES. 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. # The default value is: NO. 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. # The default directory is: xml. # This tag requires that the tag GENERATE_XML is set to YES. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a # validating XML parser to check the syntax of the XML files. # This tag requires that the tag GENERATE_XML is set to YES. XML_SCHEMA = # The XML_DTD tag can be used to specify a XML DTD, which can be used by a # validating XML parser to check the syntax of the XML files. # This tag requires that the tag GENERATE_XML is set to YES. 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. # The default value is: YES. # This tag requires that the tag GENERATE_XML is set to YES. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- # If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in # front of it. # The default directory is: docbook. # This tag requires that the tag GENERATE_DOCBOOK is set to YES. DOCBOOK_OUTPUT = docbook #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen # Definitions (see http://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. # The default value is: NO. 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. # The default value is: NO. 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. # The default value is: NO. # This tag requires that the tag GENERATE_PERLMOD is set to YES. 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. # The default value is: YES. # This tag requires that the tag GENERATE_PERLMOD is set to YES. 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. # This tag requires that the tag GENERATE_PERLMOD is set to YES. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. 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 only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set 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. # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES the includes files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 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. # This tag requires that the tag SEARCH_INCLUDES is set to YES. 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. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 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 e.g. # 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. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. 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 that overrules the # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all refrences to 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. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration options related to external references #--------------------------------------------------------------------------- # The TAGFILES tag can be used to specify one or more tag files. For each tag # file the location of the external documentation should be added. 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. See the # section "Linking to external documentation" for more information about the use # of tag files. # Note: Each tag file must have an 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. See section "Linking to # external documentation" for more information about the usage of tag files. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external class will be listed in the # class index. If set to NO only the inherited external classes will be listed. # The default value is: NO. 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. # The default value is: YES. EXTERNAL_GROUPS = YES # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. EXTERNAL_PAGES = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of 'which perl'). # The default file (with absolute path) is: /usr/bin/perl. PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more # powerful graphs. # The default value is: YES. 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. # The default value is: YES. 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 (see: # http://www.graphviz.org/), 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 value is: NO. HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of # processors available in the system. You can set it explicitly to a value # larger than 0 to get control over the balance between CPU load and processing # speed. # Minimum value: 0, maximum value: 32, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. DOT_NUM_THREADS = 0 # When you want a differently looking font n the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by # setting DOT_FONTPATH to the directory containing the font. # The default value is: Helvetica. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size (in points) of the font of # dot graphs. # Minimum value: 4, maximum value: 24, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the default font as specified with # DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set # the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = # If the CLASS_GRAPH tag is 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 CLASS_DIAGRAMS tag to NO. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside the # class node. If there are many fields or methods and many nodes the graph may # become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the # number of items for each type to make the size more manageable. Set this to 0 # for no limit. Note that the threshold may be exceeded by 50% before the limit # is enforced. So when you set the threshold to 10, up to 15 fields may appear, # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. # This tag requires that the tag HAVE_DOT is set to YES. UML_LIMIT_NUM_FIELDS = 10 # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. TEMPLATE_RELATIONS = YES # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. CALL_GRAPH = NO # If the CALLER_GRAPH tag is 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH tag is 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. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). # Possible values are: png, jpg, gif and svg. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # # Note that this requires a modern browser other than Internet Explorer. Tested # and working are Firefox, Chrome, Safari, and Opera. # Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make # the SVG files visible. Older versions of IE do not have SVG support. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. INTERACTIVE_SVG = NO # The DOT_PATH tag 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. # This tag requires that the tag HAVE_DOT is set to YES. 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). # This tag requires that the tag HAVE_DOT is set to YES. DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). MSCFILE_DIRS = # The 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 if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. # Minimum value: 0, maximum value: 10000, default value: 50. # This tag requires that the tag HAVE_DOT is set to YES. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs # generated by dot. A depth value of 3 means that only nodes reachable from the # root by following a path via at most 3 edges will be shown. Nodes that lay # further from the root node will be omitted. Note that setting this option to 1 # or 2 may greatly reduce the computation time needed for large code bases. Also # note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. # Minimum value: 0, maximum value: 1000, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not seem # to support this out of the box. # # 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). # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. 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. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES |
Added ssx/genv2.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 | /*********************************************************************** ssx/genv2.cpp - Walks the SSQLS v2 parse result, writing back out the equivalent SSQLS v2 DSL code. This is useful for testing that our parser has correctly understood a given piece of code. It is also something like the preprocessor mode of a C++ compiler, emitting a digested version of its input. Copyright (c) 2009 by Warren Young and (c) 2009-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "genv2.h" #include "parsev2.h" #include <cstring> #include <iostream> #include <fstream> #include <typeinfo> using namespace std; //// generate_ssqls2 /////////////////////////////////////////////////// // 2 versions: second checks its arguments and opens the named file, // calling the second to actually generate the SSQLS v2 output from // the parse result only if we were given sane parameters. static bool generate_ssqls2(ostream& os, const ParseV2* pparse) { ParseV2::LineListIt it; for (it = pparse->begin(); it != pparse->end(); ++it) { if (dynamic_cast<ParseV2::Field*>(*it)) { // 'field' directives must be indented under the preceding // 'table'. We don't want to hard-code this in // ParseV2::Field::print() in case we later start calling // those routines for other reasons, such as to construct // error messages. It's really a special case of -o, not // really something that print() routine should know. os << '\t'; } os << **it << endl; } return true; } bool generate_ssqls2(const char* file_name, const ParseV2* pparse) { if (pparse) { if (strcmp(file_name, "-") == 0) { return generate_ssqls2(cout, pparse); } else { ofstream ofs(file_name); if (ofs) { cout << "TRACE: Generating SSQLS v2 file " << file_name << " from " << (pparse->end() - pparse->begin()) << " line parse result." << endl; return generate_ssqls2(ofs, pparse); } else { cerr << "Failed to open " << file_name << \ " for writing for -o!" << endl; return false; } } } else { cerr << "No parse result given to -o handler!" << endl; return false; } } |
Added ssx/genv2.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 | /*********************************************************************** ssx/genv2.h - Mechanism for generating SSQLS v2 DSL code from an SSQLS v2 parse result. Implements ssqlsxlat -o flag. Copyright (c) 2009 by Warren Young. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_SSX_GENV2_H) #define MYSQLPP_SSX_GENV2_H class ParseV2; extern bool generate_ssqls2(const char* file_name, const ParseV2* pparse); #endif // !defined(MYSQLPP_SSX_GENV2_H) |
Added ssx/main.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 | /*********************************************************************** ssx/main.cpp - Main driver module for ssqlsxlat, which does several data translations related to the SSQLSv2 mechanism of MySQL++. The primary one is SSQLSv2 language files (*.ssqls) to C++ source code, but there are others. Run "ssqlsxlat -?" to get a complete list. Copyright (c) 2009 by Warren Young and (c) 2009-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "genv2.h" #include "parsev2.h" #include <cmdline.h> #include <iostream> using namespace std; using namespace mysqlpp::ssqlsxlat; //// parse_ssqls2 ////////////////////////////////////////////////////// // We were given the name of a putative SSQLS v2 source file; try to // parse it. static ParseV2* parse_ssqls2(const char* file_name) { try { cout << "Parsing SSQLS v2 file " << file_name << "..." << endl; ParseV2* pt = new ParseV2(file_name); cout << file_name << " parsed successfully, " << (pt->end() - pt->begin()) << " interesting lines." << endl; return pt; } catch (const ParseV2::FileException& e) { cerr << file_name << ":0" << ": file I/O error in SSQLS v2 parse: " << e.what() << endl; } catch (const ParseV2::ParseException& e) { cerr << e.file_name() << ':' << e.line() << ':' << e.what() << endl; } catch (const std::exception& e) { cerr << file_name << ":0" << ": critical error in SSQLS v2 parse: " << e.what() << endl; } return 0; } //// main ////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { // Parse the command line CommandLine cmdline(argc, argv); if (cmdline) { ParseV2* ptree = 0; switch (cmdline.input_source()) { case CommandLine::ss_ssqls2: ptree = parse_ssqls2(cmdline.input()); break; default: cerr << "Sorry, I don't yet know what to do with input " "source type " << int(cmdline.input_source()) << '!' << endl; return 2; } if (cmdline.output_sink() != CommandLine::ss_unknown) { if (ptree) { switch (cmdline.output_sink()) { case CommandLine::ss_ssqls2: if (generate_ssqls2(cmdline.output(), ptree)) { return 0; } else { return 2; } default: cerr << "Sorry, I don't yet know what to do " "with sink type " << int(cmdline.output_sink()) << '!' << endl; return 2; } } else { // Depending on someone farther up the line to write // the error message, explaining why we didn't get a // parse tree. return 2; } } else { cerr << "Sorry, I don't know how to write C++ output yet." << endl; return 2; } } else { return 1; } } |
Added ssx/parsev2.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 | /*********************************************************************** ssx/parsev2.cpp - Parser for the SSQLS v2 language. Copyright (c) 2009 by Warren Young. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "parsev2.h" #include <utility.h> #include <algorithm> #include <cassert> #include <cctype> #include <cerrno> #include <cstring> #include <iostream> using namespace std; // System error value to string conversion #if defined(MYSQLPP_PLATFORM_WINDOWS) # define SYSERR "" #else # define SYSERR ": " << strerror(errno) #endif //////////////////////////////////////////////////////////////////////// // Instantiate static members ParseV2::StringList ParseV2::File::search_path_; ParseV2::ParseV2(const char* file_name) : file_(file_name) { // For each line in the file, read it in and try to make sense of it // based on the indent level and the leading verb. //cout << "TRACE: parsing SSQLS v2 file " << file_name << '.' << endl; string line; bool subdirective; while (file_.read_line(line, subdirective)) { // Skip empty lines if (line.empty()) continue; // Break line up into whitespace-separated tokens StringList tokens; tokenize(tokens, line); if (tokens.empty()) continue; // shouldn't happen // Try to interpret token list Line* line = Line::parse(tokens, subdirective, file_); assert(line != 0); // errors should be signalled with exceptions Include* iline = dynamic_cast<Include*>(line); if (iline) { // Include lines are a special case: we hoist the parsed // lines from the included file up into our line list. lines_.reserve(lines_.size() + (iline->end() - iline->begin())); for (LineListIt it = iline->begin(); it != iline->end(); ++it) { lines_.push_back(*it); } delete iline; } else { // Normal case: add line to our line list lines_.push_back(line); } } } void ParseV2::tokenize(StringList& tokens, const std::string& line) const { // Skip over leading whitespace string::const_iterator current = line.begin(); while (current != line.end() && isspace(*current)) { ++current; } // Break rest of line up into space-separated words, treating // consecutive spaces as single separators, and ignoring trailing // spaces. while (current != line.end()) { string::const_iterator word_start = current; while (current != line.end() && !isspace(*current)) ++current; tokens.push_back(string(word_start, current)); while (current != line.end() && isspace(*current)) ++current; } #if 0 cout << "TRACE: " << tokens.size() << " tokens in line '" << line << "':" << endl; cout << "\t"; for (StringListIt it = tokens.begin(); it != tokens.end(); /* */) { cout << '\'' << *it++ << '\''; if (it != tokens.end()) cout << ','; } cout << endl; #endif } void ParseV2::AccessorStyleOption::print(std::ostream& os) const { os << "option accessor_style "; switch (type_) { case camel_case_lower: os << "getX"; break; case camel_case_upper: os << "GetX"; break; case overloaded: os << "x"; break; case stroustrup: os << "get_x"; break; case unknown: os << "UNKNOWN"; break; } } ParseV2::AccessorStyleOption::Type ParseV2::AccessorStyleOption::parse_type(const std::string& style, const File& file) { //cout << "TRACE: found accessor style " << style << endl; if (style.compare("getX") == 0) { return camel_case_lower; } else if (style.compare("GetX") == 0) { return camel_case_upper; } else if (style.compare("get_x") == 0) { return stroustrup; } else if (style.compare("x") == 0) { return overloaded; } else { ostringstream o; o << "unknown accessor style '" << style << '\''; file.parse_error(o); return unknown; } } void ParseV2::ExceptionOnSchemaMismatchOption::print(std::ostream& os) const { os << "option exception_on_schema_mismatch " << (throw_ ? "true" : "false"); } ParseV2::Field* ParseV2::Field::parse(const StringList& tl, bool subdirective, const File& file) { // Check for obviously wrong inputs if (tl.size() < 2) { file.parse_error("'field' directive requires at least one argument"); } else if (!subdirective) { file.parse_error("'field' must be a subdirective"); } // Get field name StringListIt it = ++tl.begin(); // skip over 'field' string name(*it++); //cout << "TRACE: found field " << name << endl; // Scan rest of token list, interpreting the name/value pairs. string type, alias; bool is_autoinc = false, is_key = false, is_null = false, is_unsigned = false; while (tl.end() - it > 1) { string attr(*it++), value(*it++); mysqlpp::internal::str_to_lwr(attr); if (attr.compare("alias") == 0) { alias = value; } else if (attr.compare("is") == 0) { if (value.compare("autoinc") == 0) { is_autoinc = true; } else if (value.compare("key") == 0) { is_key = true; } else if (value.compare("null") == 0) { is_null = true; } else if (value.compare("unsigned") == 0) { is_unsigned = true; } else { ostringstream o; o << "unknown is-attribute '" << value << "' for field '" << name << '\''; file.parse_error(o); } } else if (attr.compare("type") == 0) { type = value; } else { ostringstream o; o << "bad attribute '" << attr << "' for field " << name; file.parse_error(o); } } // Warn if field wasn't given an explicit type if (type.empty()) { cerr << "Warning: field '" << name << "' defaulting to " "string type." << endl; } // No attribute errors, so create the Field object. return new Field(name, type, is_unsigned, is_null, is_autoinc, is_key, alias); } void ParseV2::Field::print(std::ostream& os) const { os << "field " << name_ << ' '; type_.print(os); if (is_autoinc_) os << " is autoinc"; if (is_key_) os << " is key"; if (is_null_) os << " is null"; if (is_unsigned_) os << " is unsigned"; if (alias_.size()) os << " alias " << alias_; } ParseV2::Field::Type::Type(const std::string& s) : value_(ft_string) { // Force s to lowercase as ls, for easier comparisons below string ls(s); mysqlpp::internal::str_to_lwr(ls); //cout << "TRACE: field type " << s << endl; // Suss out appropriate field type in piecewise fashion. This // parser isn't terribly robust, but it should do sane things in the // presence of plausible input. Feed it garbage, and the worst that // will happen is that it will either give up, letting the default // of ft_string stand, or it may happen to recognize some substring // in the input that causes it to assign some other type. if ((ls.find("blob") != string::npos) || (ls.find("varbinary") != string::npos)) { value_ = ft_blob; } else if (ls.find("bool") == 0) { value_ = ft_tinyint; } else if (ls.find("date") == 0) { if (ls.compare("datetime") == 0) value_ = ft_datetime; else value_ = ft_date; } else if ((ls.find("decimal") != string::npos) || (ls.find("double") != string::npos) || (ls.find("fixed") != string::npos) || (ls.find("numeric") != string::npos)) { value_ = ft_double; } else if (ls.find("float") != string::npos) { value_ = ft_float; } else if (ls.find("int") != string::npos) { if (ls.find("tiny") == 0) value_ = ft_tinyint; else if (ls.compare("int1") == 0) value_ = ft_tinyint; else if (ls.find("small") == 0) value_ = ft_smallint; else if (ls.compare("int2") == 0) value_ = ft_smallint; else if (ls.find("big") == 0) value_ = ft_bigint; else if (ls.compare("int8") == 0) value_ = ft_bigint; else value_ = ft_mediumint; } else if (ls.find("set") != string::npos) { value_ = ft_set; } else if (ls.find("time") == 0) { if (ls.compare("timestamp") == 0) value_ = ft_datetime; else value_ = ft_time; } } void ParseV2::Field::Type::print(std::ostream& os) const { os << "type "; switch (value_) { case ft_bigint: os << "bigint"; break; case ft_blob: os << "blob"; break; case ft_date: os << "date"; break; case ft_datetime: os << "datetime"; break; case ft_double: os << "double"; break; case ft_float: os << "float"; break; case ft_mediumint: os << "mediumint"; break; case ft_set: os << "set"; break; case ft_smallint: os << "smallint"; break; case ft_string: os << "string"; break; case ft_time: os << "time"; break; case ft_tinyint: os << "tinyint"; break; } } ParseV2::File::File(const char* file_name) : file_name_(file_name), line_number_(1) { // Try to open the named file for reading //cout << "TRACE: opening file " << file_name << endl; StringListIt it = search_path_.begin(); string path(file_name_); while (true) { ifs_.open(path.c_str()); if (ifs_) { // Opened it, so add directory part of file path (if any) to // our search path. add_directory_to_search_path(file_name); break; } else if (it == search_path_.end()) { // Ran out of things to try ostringstream o; o << "Failed to open '" << file_name_ << "' for reading" << SYSERR; error(o); } else { // Replace previous path with the next possibility, which // we'll try on the next iteration. path = *it++; path += MYSQLPP_PATH_SEPARATOR; path += file_name_; } } } void ParseV2::File::add_directory_to_search_path(const char* filepath) { //cout << "TRACE: adding directory part of " << filepath << // " to search path." << endl; StringList parts; split_path(parts, filepath); if (parts.size() > 1) { // There's a path part, so check that it's not just '.', the // current directory on all the systems we're portable to. if (parts.size() != 2 || parts[0].compare(".") != 0) { // Path is interesting, so reassemble the directory part string path(parts[0]); StringListIt it = ++parts.begin(); while (it < parts.end() - 1) { // ignore last part; file name path += MYSQLPP_PATH_SEPARATOR; path += *it++; } // Add that directory to the search path unless it's already // in the list. if (find(search_path_.begin(), search_path_.end(), path) == search_path_.end()) { search_path_.push_back(path); //cout << "TRACE: added new directory " << path << // " to search path." << endl; } } } } void ParseV2::File::error(const std::string& msg) const { throw FileException(msg); } void ParseV2::File::parse_error(const std::string& msg) const { throw ParseException(msg, file_name_, line_number_); } bool ParseV2::File::read_line(std::string& line, bool& subdirective) { line.clear(); if (ifs_) { static char temp[100]; ifs_.getline(temp, sizeof(temp)); if (ifs_) { ++line_number_; line = temp; size_t n = line.find('#'); if (n != string::npos) { line.resize(n); } if (line.size()) { subdirective = isspace(line[0]); } return true; } } return false; } void ParseV2::File::split_path(StringList& parts, const std::string& path) const { //cout << "TRACE: splitting path '" << path << "'..." << endl; const char sep = MYSQLPP_PATH_SEPARATOR; for (string::const_iterator it = path.begin(); it < path.end(); /* */) { string::const_iterator part_start = it; while (it != path.end() && (*it != sep)) ++it; parts.push_back(string(part_start, it)); while (it != path.end() && (*it == sep)) ++it; } #if 0 cout << "TRACE: " << parts.size() << " parts in path '" << path << "': "; for (StringListIt it = parts.begin(); it != parts.end(); /* */) { cout << *it++; if (it != parts.end()) cout << sep; } cout << endl; #endif } void ParseV2::HeaderExtensionOption::print(std::ostream& os) const { os << "option header_extension " << value(); } void ParseV2::ImplementationExtensionOption::print(std::ostream& os) const { os << "option implementation_extension " << value(); } ParseV2::Include* ParseV2::Include::parse(const StringList& tl, bool subdirective, const File& file) { // Check for obviously wrong inputs if (tl.size() != 2) { file.parse_error("'include' directive requires one argument"); } else if (subdirective) { file.parse_error("'include' cannot be a subdirective"); } // Above ensures that there is only one argument, so create Include // object from it, assuming it's a file name. //cout << "TRACE: including " << tl[0] << "..." << endl; return new Include((++tl.begin())->c_str()); } ParseV2::Line* ParseV2::Line::parse(const StringList& tl, bool subdirective, const File& file) { // True if the last top-level directive we saw was 'table' static bool last_tld_was_table = false; // Pull the directive off the front of the list assert(!tl.empty()); string directive(tl[0]); // First, recognize directives that expect subdirectives. mysqlpp::internal::str_to_lwr(directive); //cout << "TRACE: found " << directive << " line." << endl; if (directive.compare("table") == 0) { if (!subdirective) last_tld_was_table = true; return ParseV2::Table::parse(tl, subdirective, file); } else { // Next recognize directives that either stand alone at the top // level, or are always subdirectives. if (!subdirective) { last_tld_was_table = false; } if (directive.compare("field") == 0) { if (last_tld_was_table) { return ParseV2::Field::parse(tl, subdirective, file); } else { file.parse_error("'field' directive must follow 'table'"); } } else if (directive.compare("include") == 0) { return ParseV2::Include::parse(tl, subdirective, file); } else if (directive.compare("option") == 0) { return ParseV2::Option::parse(tl, subdirective, file); } } // None of the code above recognized the directive. Yell about it // with an exception. Return doesn't actually happen, it just // squishes a compiler warning. ostringstream o; o << "unrecognized directive '" << directive << '\''; file.parse_error(o); return 0; } ParseV2::Option* ParseV2::Option::parse(const StringList& tl, bool subdirective, const File& file) { // Check for obviously wrong inputs if (tl.size() != 3) { file.parse_error("'option' directive requires two arguments"); } else if (subdirective) { file.parse_error("'option' cannot be a subdirective"); } // See if we can make sense of the first argument, which should be // the option name. string name(tl[1]); string value(tl[2]); //cout << "TRACE: found " << name << " = '" << value << // "' option." << endl; if (name.compare("accessor_style") == 0) { return new AccessorStyleOption(value, file); } else if (name.compare("exception_on_schema_mismatch") == 0) { return new ExceptionOnSchemaMismatchOption(value); } else if (name.compare("header_extension") == 0) { return new HeaderExtensionOption(value); } else if (name.compare("implementation_extension") == 0) { return new ImplementationExtensionOption(value); } else { ostringstream o; o << "unknown option '" << name << '\''; file.parse_error(o); return 0; } } bool ParseV2::Option::parse_bool(const std::string& value) { // Lowercase the given string for easier comparison string b(value); mysqlpp::internal::str_to_lwr(b); // Recognize only known falsy values, as SSQLS v2 options all // default to false, so the assumption is that any option that's // set at all is almost certainly to flip it from its default, to // true. So, only definite false values are actually critical to // recognize, that being the surprising case. return !( b.compare("0") == 0 || b.compare("false") == 0 || b.compare("no") == 0 || b.compare("off") == 0 ); } ParseV2::Table::Table(const std::string& name, const std::string& alias, const std::string& filebase) : name_(name), alias_(alias.empty() ? name : alias), filebase_(filebase.empty() ? name : filebase) { } ParseV2::Table* ParseV2::Table::parse(const StringList& tl, bool subdirective, const File& file) { // Check for obviously wrong inputs if (tl.size() < 2) { file.parse_error("'table' directive requires at least one argument"); } else if (subdirective) { file.parse_error("'table' cannot be a subdirective"); } // Get table name StringListIt it = ++tl.begin(); // skip over 'table' string name(*it++); //cout << "TRACE: found '" << name << "' table." << endl; // Scan rest of token list, interpreting the name/value pairs. string alias, filebase; while (tl.end() - it > 1) { string attr(*it++), value(*it++); mysqlpp::internal::str_to_lwr(attr); if (attr.compare("alias") == 0) { alias = value; } else if (attr.compare("filebase") == 0) { filebase = value; } else { ostringstream o; o << "bad attribute '" << attr << "' for table " << name; file.parse_error(o); } } // No attribute errors, so create the Table object. return new Table(name, alias, filebase); } void ParseV2::Table::print(std::ostream& os) const { os << "table " << name_; if (alias_.size()) os << " alias " << alias_; if (filebase_.size()) os << " filebase " << filebase_; } ostream& operator<<(ostream& os, const ParseV2::Line& line) { line.print(os); return os; } |
Added ssx/parsev2.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 | /*********************************************************************** ssx/parsev2.h - Declares the SSQLS v2 language parsing related classes. Copyright (c) 2009 by Warren Young and (c) 2009-2010 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_SSX_PARSEV2_H) #define MYSQLPP_SSX_PARSEV2_H #include <exceptions.h> #include <cassert> #include <fstream> #include <string> #include <vector> /// \brief Parses SSQLS v2 documents and holds the parse result /// /// Construct an object of this type from a file name, and you will /// get either a parse result or a thrown exception. class ParseV2 { public: /// \brief List of tokens as returned by boost::algorithm::split typedef std::vector<std::string> StringList; /// \brief Iterator into a StringList /// /// This is const because StringLists are never modified once created typedef StringList::const_iterator StringListIt; /// \brief Holds information about an SSQLS v2 file we're parsing /// /// This class exists simply because there's so much file-related /// processing in the parser, and it's confusing to have it /// scattered about. class File { public: /// \brief Open a file for reading, using the search path to /// file the file if the direct path isn't readable. File(const char* file_name); /// \brief Throw a FileException containing the given message void error(const std::string& msg) const; /// \sa error(const std::string&) void error(const std::ostringstream& msg) const { error(msg.str()); } /// \brief Return the file's name const char* name() const { return file_name_.c_str(); } /// \brief Throw a ParseException containing the given message /// and our stored info about the file name and current line void parse_error(const std::string& msg) const; /// \sa parse_error(const std::string&) void parse_error(const std::ostringstream& msg) const { error(msg.str()); } /// \brief Read a line in from a file /// /// We read the line from our internal file object, trimming any /// trailing comment. Does \e not trim whitespace; we depend on /// ParseV2::tokenize() to cope with that. Sets subdirective /// flag if we see leading whitespace before we trim it away, as /// indented lines are interpreted differently by File's users. /// /// \return false if our internal file object is in an error /// condition on entering or exiting this function. bool read_line(std::string& line, bool& subdirective); private: /// \brief Given the path to a file that is known to exist, /// extract the directory part (if any) and apppend it to our /// file search path. /// /// This allows 'include' directives to find other files in the /// same directory as the included file when the first inclusion /// refers to a file not in the current directory. Because the /// search path is static, it doesn't matter who "learns" about /// a useful directory. Every file open from there on benefits. void add_directory_to_search_path(const char* filepath); /// \brief Break a file path up into a series of elements by the /// platform's directory separator, dropping '.' elements. void split_path(StringList& parts, const std::string& path) const; /// \brief File we're reading from std::ifstream ifs_; /// \brief Name of we're parsing /// /// Used to construct useful error messages std::string file_name_; /// \brief Line number in file we're parsing /// /// Used to construct useful error messages size_t line_number_; /// \brief Directories used in searching for included files /// /// This is a \c vector, rather than a \c set, because order /// matters. We grow this list as we go deeper into an inclusion /// tree, with the earlier paths taking precedence. /// /// It's static because we only need on search path, and want /// new additions to inform all future parses in this session. static StringList search_path_; }; //// Types of parsed lines, and related stuff /// \brief Base class for parsed SSQLS v2 declaration lines class Line { public: /// \brief Virtual dtor, since this is a base class virtual ~Line() { } /// \brief Virtual ctor, creating one of our subclass objects /// based on what we're passed /// /// \param tl list of tokens found on a line in an SSQLS v2 file /// \param subdirective true if there was leading whitespace on /// that line, which changes how we interpret tl /// \param file information about the file we're currently parsing /// /// \return Line object pointer if line was successfully parsed, /// else 0 static Line* parse(const StringList& tl, bool subdirective, const File& file); /// \brief Print line's contents out to a stream in SSQLS v2 /// form. virtual void print(std::ostream& os) const = 0; protected: /// \brief Protected ctor, to prevent instantiation Line() { } }; /// \brief A list of pointers to Line objects /// /// These are used for holding the results of the file parsing step typedef std::vector<Line*> LineList; /// \brief Iterator into a LineList /// /// It's const because once the parse is completed, we switch into /// LineList traversal mode, which doesn't modify the list. typedef LineList::const_iterator LineListIt; /// \brief 'field' directive line class Field : public Line { public: /// \brief Holds information about a SQL field declared in /// the SSQLS v2 language /// /// \param type the field's SQL type /// \param is_unsigned true if type is an integer and is unsigned /// \param is_null true if field's value is nullable /// \param is_autoinc true if DB automatically assigns an /// auto-incrementing value to this field in INSERT if /// it isn't specified /// \param is_key true if field is part of the primary key /// \param name the field's SQL name /// \param alias the field's C++ name, defaulting to the SQL /// name Field(const std::string& name, const std::string& type, bool is_unsigned = false, bool is_null = false, bool is_autoinc = false, bool is_key = false, const std::string& alias = 0) : name_(name), type_(type), is_autoinc_(is_autoinc), is_key_(is_key), is_null_(is_null), is_unsigned_(is_unsigned), alias_(alias) { } /// \brief Attempt to create a Field object from information in /// the passed StringList /// /// A kind of pre-processor for the Field ctor, creating one of /// those objects only if the given StringList makes sense, /// using the values we find in that StringList as parameters to /// the ctor. static Field* parse(const StringList& tl, bool subdirective, const File& file); /// \brief Print field description out to a stream in SSQLS v2 /// form. void print(std::ostream& os) const; /// \brief A smart enum for converting SQL type strings to one /// of a relatively few types we directly support. /// /// This object defaults to a value of ft_string if the type /// cannot be discerned. /// /// This class is public only to allow it to be tested, in /// test/ssqls2.cpp. It shouldn't actually be used outside /// ssqlsxlat. class Type { public: /// \brief Known SQL field types /// /// This list is shorter than what we support in MySQL++'s /// lib/sql_types.h and shorter still than the full list of /// types that SQL database engines support. Its length is /// limited by the diversity of data types in C++ and /// MySQL++. We map SQL types to one of these values as /// best we can. /// /// This list doesn't encode anything about nullness, /// signedness, etc. Those are considered attributes modifying /// the type, not creating independent data types. We store /// these flags in separate variables in the outer class. enum Value { ft_tinyint, ///< TINYINT, INT1, BOOL ft_smallint, ///< SMALLINT, INT2 ft_mediumint, ///< INT, MEDIUMINT, INT3, INT4 ft_bigint, ///< BIGINT, INT8 ft_float, ///< FLOAT, FLOAT4, FLOAT8 ft_double, ///< DOUBLE, DECIMAL, FIXED, NUMERIC ft_string, ///< *CHAR, ENUM, *TEXT ft_blob, ///< *BLOB, VARBINARY ft_date, ///< DATE ft_datetime, ///< DATETIME, TIMESTAMP ft_time, ///< TIME ft_set ///< SET }; /// \brief Constructor /// /// Given a SQL type string, try to figure out which of the /// relatively small set of known values to use. Defaults /// to ft_string if we can't find a more appropriate type, /// as all SQL values can be dealt with as strings. Type(const std::string& s); /// \brief Copy constructor Type(Value v) : value_(v) { } /// \brief Print type description out to a stream in /// SSQLS v2 form. void print(std::ostream& os) const; /// \brief Enum value accessor operator Value() const { return value_; } /// \brief Equality operator bool operator ==(const Type& rhs) const { return value_ == rhs.value_; } private: Value value_; }; private: std::string name_; ///< the field's SQL name Type type_; ///< the field's SQL type bool is_autoinc_; ///< true if DB autoincrements this column if left out of INSERT bool is_key_; ///< true if field is part of the primary key bool is_null_; ///< true if field's value is nullable bool is_unsigned_; ///< true if field has unsigned integer type std::string alias_; ///< the field's C++ name }; /// \brief 'include' directive line class Include : public Line { public: /// \brief Given the name of another SSQLS v2 file, load it /// up and parse it. Its contents will appear transparently /// as part of the overall parse result. /// /// \param file_name name of other SSQLS v2 file to parse Include(const char* file_name) : pp2_(new ParseV2(file_name)) { } /// \brief Destructor ~Include() { pp2_->clear(); delete pp2_; } /// \brief Get an iterator pointing to the start of the // sub-parse's LineList LineListIt begin() const { return pp2_->begin(); } /// \brief Get an iterator pointing to just past the end of the /// sub-parse's LineList LineListIt end() const { return pp2_->end(); } /// \brief Attempt to create an Include object from information /// in the passed StringList /// /// A kind of pre-processor for the Include ctor, creating one /// of those objects only if the given StringList makes sense, /// using the values we find in that StringList as parameters to /// the ctor. static Include* parse(const StringList& tl, bool subdirective, const File& file); private: // Never called. Include directives don't appear in the parse // list; the included file's contents appear in its place // instead. Since this method only exists to test parsing // behavior, we can't be called. void print(std::ostream&) const { assert(0); } /// \brief pointer to the object holding parse details for /// the other file we were constructed with ParseV2* pp2_; }; /// \brief Base class for known SSQLS v2 'option' directives /// /// There are subclasses for all known SSQLS v2 options, having /// the same name, but with different capitalization and an /// "Option" suffix. class Option : public Line { public: /// \brief Virtual dtor, since this is a base class virtual ~Option() { } /// \brief Attempt to create an Option object from information /// in the passed StringList /// /// This is a kind of pre-processor for the Option subclass's /// ctors, creating an object of one of those subclasses only if /// the given StringList makes sense, passing those values as /// ctor parameters. static Option* parse(const StringList& tl, bool subdirective, const File& file); protected: /// \brief Protected ctor, so we cannot be directly instantiated /// /// \param value the option's value Option(const std::string& value) : value_(value) { } /// \brief Convert a string expressing a boolean value to a \c bool /// /// If we cannot recognize the value, we return true because /// SSQLS v2 options all default to false. The assumption is is /// that if the option directive is present, the value is most /// likely truthy. /// /// As a consequence, the only thing this function recognizes is /// "0", "false", "no", and "off", with any mix of upper and /// lower case. All else is considered \c true. static bool parse_bool(const std::string& value); /// \brief Return the option's value in string form, unmodified /// from the original parse /// /// Subclasses typically either expose this function in their /// public interface with a different, more appropriate name, or /// they define a wholly different method returning a reduced or /// more type-safe version of this value. const char* value() const { return value_.c_str(); } private: // The option's raw value string std::string value_; }; /// \brief 'option accessor_style' directive line class AccessorStyleOption : public Option { public: /// \brief Constructor AccessorStyleOption(const std::string& value, const File& file) : Option(value), type_(AccessorStyleOption::parse_type(value, file)) { } /// \brief Print the option description out to a stream in /// SSQLS v2 form. void print(std::ostream& os) const; private: /// \brief Known accessor styles /// /// \internal We could implement this by deepening the Option /// hierarchy, making this a base class, with the known styles /// each implemented as a subclass, but that's seems excessively /// OO-dogmatic. enum Type { unknown, ///< bad style value found in .ssqls file camel_case_lower, ///< generate accessors like \c getX() camel_case_upper, ///< generate accessors like \c GetX() stroustrup, ///< generate accessors like \c get_x() overloaded ///< same method name for setter and getter }; /// \brief Given a raw accessor style value straight from the /// parser, try to figure out which of the known styles is /// meant. static Type parse_type(const std::string& style, const File& file); /// \brief Parsed accessor style type Type type_; }; /// \brief 'option exception_on_schema_mismatch' directive line class ExceptionOnSchemaMismatchOption : public Option { public: /// \brief Constructor ExceptionOnSchemaMismatchOption(const std::string& value) : Option(value), throw_(Option::parse_bool(value)) { } /// \brief Return true if our emitted C++ code is supposed to /// throw an exception on schema mismatches operator bool() const { return throw_; } /// \brief Print the option description out to a stream in /// SSQLS v2 form. void print(std::ostream& os) const; private: bool throw_; ///< parsed version of parent's value }; /// \brief 'option header_extension' directive line class HeaderExtensionOption : public Option { public: /// \brief Constructor HeaderExtensionOption(const std::string& value) : Option(value) { } /// \brief Return the extension used for C++ headers we emit const char* extension() const { return value(); } /// \brief Print the option description out to a stream in /// SSQLS v2 form. void print(std::ostream& os) const; }; /// \brief 'option implementation_extension' directive line class ImplementationExtensionOption : public Option { public: /// \brief Constructor ImplementationExtensionOption(const std::string& value) : Option(value) { } /// \brief Return the extension used for C++ implementation /// files we emit const char* extension() const { return value(); } /// \brief Print the option description out to a stream in /// SSQLS v2 form. void print(std::ostream& os) const; }; /// \brief 'table' directive line class Table : public Line { public: /// \brief Constructor /// /// \param name the table's SQL name /// \param alias the table's C++ name; defaults to \c name /// \param filebase the base name used for generated C++ code /// files; defaults to \c name Table(const std::string& name, const std::string& alias, const std::string& filebase); /// \brief Attempt to create a Table object from information in /// the passed StringList /// /// A kind of pre-processor for the Table ctor, creating a Table /// object only if the given StringList makes sense, using the /// values we find in that StringList as parameters to the Table /// ctor. static Table* parse(const StringList& tl, bool subdirective, const File& file); /// \brief Print the table description out to a stream in /// SSQLS v2 form. void print(std::ostream& os) const; private: std::string name_, alias_, filebase_; }; //// Exception types /// \brief Exception object thrown to indicate a file I/O error class FileException : public mysqlpp::Exception { public: /// \brief Constructor /// /// \param what description of what went wrong reading the /// SSQLS v2 file FileException(const std::string& what) : Exception(what) { } }; /// \brief Exception object thrown by File::error() to report /// an SSQLS v2 parsing error class ParseException : public mysqlpp::Exception { public: /// \brief Constructor /// /// \param what description of what went wrong parsing the line /// \param file_name name of source file where error occurred /// \param line line number in source file where error occurred ParseException(const std::string& what, const std::string& file_name, size_t line) : Exception(what), file_name_(file_name), line_(line) { } /// \brief Destructor ~ParseException() throw() { } /// \brief Get name of file where error occurred const char* file_name() const { return file_name_.c_str(); } /// \brief Get line number where error occurred size_t line() const { return line_; } private: std::string file_name_; size_t line_; }; /// \brief Constructor /// /// Given the name of an SSQLS v2 file, load it up and try to parse /// it, throwing one of our inner exception types if that fails. /// /// \param file_name path to an SSQLS v2 file to parse; may be in a /// different directory, given a relative or absolute path /// to the file /// /// \throw FileException /// \throw ParseException ParseV2(const char* file_name); /// \brief Destructor ~ParseV2() { for (LineListIt it = lines_.begin(); it != lines_.end(); ++it) { delete *it; } } /// \brief Get an iterator pointing to the start of our LineList LineListIt begin() const { return lines_.begin(); } /// \brief Dump our line list /// /// Doesn't delete the line objects. This is used by Include, /// because its creator will take over ownership of those objects. void clear() { lines_.clear(); } /// \brief Get an iterator pointing just past the end of our LineList LineListIt end() const { return lines_.end(); } private: /// \brief Break line up into a series of space-separated words void tokenize(StringList& tokens, const std::string& line) const; /// \brief Information about the file we're currently parsing File file_; /// \brief List of Line object pointers representing the parse result /// /// This does not contain Line sub-classes for subdirectives. You /// will find a LineList inside the top-level directive class. /// /// You will not find Include objects in this list corresponding to /// any 'include' directives in the input file. On finishing the /// recursive parse for the included file, we pull its LineList /// contents up into this level. This flattens the recursive parse /// so the code doing the traversal doesn't have to worry about it. LineList lines_; }; /// \brief Write a Line out to a stream in SSQLS v2 form. /// /// \internal This is implemented in terms of ParseV2::Line::print() /// because operator<< needs to be a global function. This trick lets /// us get polymorphic behavior when writing Line objects out. std::ostream& operator<<(std::ostream& os, const ParseV2::Line& line); #endif // !defined(MYSQLPP_SSX_PARSEV2_H) |
Added test/array_index.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 | /*********************************************************************** test/array_index.cpp - Tests operator[] and at() on indexable objects to ensure they throw exceptions when given bad indices. Copyright (c) 2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> template <class ContainerT> static bool test_exception(const ContainerT& container, int index) { try { container[index]; container.at(index); std::cerr << "Bad index " << index << " allowed in " << typeid(container).name() << '!' << std::endl; return false; } catch (const mysqlpp::BadIndex&) { return true; } catch (const mysqlpp::Exception& e) { std::cerr << "Unexpected mysqlpp::Exception caught for " << typeid(container).name() << ", index " << index << ": " << e.what() << std::endl; return false; } catch (const std::exception& e) { std::cerr << "Unexpected std::exception caught for " << typeid(container).name() << ", index " << index << ": " << e.what() << std::endl; return false; } catch (...) { std::cerr << "Unexpected exception type caught for " << typeid(container).name() << ", index " << index << '!' << std::endl; return false; } } template <class ContainerT> static bool test_no_exception(const ContainerT& container) { mysqlpp::NoExceptions ne(container); try { container[-1]; std::cerr << "Mandatory exception suppressed for " << typeid(container).name() << "::operator[]()!" << std::endl; return false; } catch (...) { } try { container.at(-1); std::cerr << "Mandatory exception suppressed for " << typeid(container).name() << "::at()!" << std::endl; return false; } catch (...) { return true; } } // Separate test needed because string indices work different from // integer indices. Exceptions for bad field names *can* be suppressed; // SSQLS needs this to support population of partial structures, with // the un-queried fields getting default values. template <class ContainerT> static bool test_string_index(const ContainerT& container) { // This test should cause an exception... try { container["fred"]; std::cerr << "Bad string index allowed in " << typeid(container).name() << '!' << std::endl; return false; } catch (const mysqlpp::BadFieldName&) { // Good; fall through to next test } catch (const mysqlpp::Exception& e) { std::cerr << "Unexpected mysqlpp::Exception caught for " "bad string index in " << typeid(container).name() << ": " << e.what() << std::endl; return false; } catch (const std::exception& e) { std::cerr << "Unexpected std::exception caught for " "bad string index in " << typeid(container).name() << ": " << e.what() << std::endl; return false; } catch (...) { std::cerr << "Unexpected exception type caught for " "bad string index in " << typeid(container).name() << '!' << std::endl; return false; } // ...but not this one mysqlpp::NoExceptions ne(container); try { container["fred"]; return true; } catch (const mysqlpp::BadFieldName&) { std::cerr << "Exception not suppressed for nonexistent field " "in " << typeid(container).name() << '!' << std::endl; return false; } } template <class ContainerT> static bool test_numeric_index(const ContainerT& container) { return test_exception(container, -1) && test_exception(container, 0) && test_exception(container, 1); } int main() { try { return test_no_exception(mysqlpp::Row()) && test_numeric_index(mysqlpp::Row()) && test_string_index(mysqlpp::Row()) ? 0 : 1; } catch (...) { std::cerr << "Unhandled exception caught by array_index!" << std::endl; return 2; } } |
Added test/cpool.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 | /*********************************************************************** test/cpool.cpp - Tests the ConnectionPool class. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. and (c) 2007 by Jonathan Wakely. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <cpool.h> #include <connection.h> #include <iostream> #if defined(MYSQLPP_PLATFORM_WINDOWS) # define SLEEP(n) Sleep((n) * 1000) #else # include <unistd.h> # define SLEEP(n) sleep(n) #endif using namespace std; class TestConnection : public mysqlpp::Connection { public: TestConnection() : itime_(time(0)) { } time_t instantiation_time() const { return itime_; } private: time_t itime_; }; class TestConnectionPool : public mysqlpp::ConnectionPool { public: ~TestConnectionPool() { clear(); } unsigned int max_idle_time() { return 1; } private: TestConnection* create() { return new TestConnection; } void destroy(mysqlpp::Connection* cp) { delete cp; } }; int main() { TestConnectionPool pool; mysqlpp::Connection* conn1 = pool.grab(); mysqlpp::Connection* conn2 = pool.grab(); if (conn1 == conn2) { cerr << "Pool returned the same connection twice!" << endl; return 1; } pool.release(conn2); mysqlpp::Connection* conn3 = pool.grab(); if (conn2 != conn3) { cerr << "conn2 should have been reused but wasn't!" << endl; return 1; } time_t itime_c1 = dynamic_cast<TestConnection*>(conn1)-> instantiation_time(); pool.release(conn1); SLEEP(pool.max_idle_time() + 1); mysqlpp::Connection* conn4 = pool.grab(); time_t itime_c4 = dynamic_cast<TestConnection*>(conn4)-> instantiation_time(); if (itime_c1 == itime_c4) { cerr << "conn1 should have been destroyed but wasn't!" << endl; return 1; } pool.release(conn3); pool.release(conn4); pool.shrink(); if (!pool.empty()) { cerr << "Shrunken pool is not empty!" << endl; return 1; } return 0; } |
Added test/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 | /*********************************************************************** test/datetime.cpp - Tests the Date, DateTime, and Time classes. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> #include <sstream> #include <string> #include <stdio.h> using namespace mysqlpp; using namespace std; // Compare the given string against the object inserted into a Query stream. template <class T> static unsigned int test_query_insert(const T& object, const char* expected, const char* what) { Query q = Connection().query(); // don't do this in real code q << object; if (q.str().compare(expected) == 0) { cout << what << " is '" << expected << "' in Query, as expected." << endl; return 0; } else { cerr << what << " '" << object << "' should be '" << expected << "' when inserted into Query!" << endl; return 1; } } // Compare the given string against the object inserted into an ostream. template <class T> static unsigned int test_ostream_insert(const T& object, const char* expected, const char* what) { ostringstream os; os << object; if (os.str().compare(expected) == 0) { cout << what << " is '" << expected << "' in ostream, as expected." << endl; return 0; } else { cerr << what << " '" << object << "' should be '" << expected << "' when inserted into ostream!" << endl; return 1; } } // Compare the given string against the return value of the object's // str() method. template <class T> static unsigned int test_str_method(const T& object, const char* expected, const char* what) { if (object.str().compare(expected) == 0) { cout << what << ".str() returns '" << expected << "', as expected." << endl; return 0; } else { cerr << what << " '" << object << "' should return '" << expected << "' from str() method!" << endl; return 1; } } // Compare the given string against the object when cast to std::string template <class T> static unsigned int test_string_operator(const T& object, const char* expected, const char* what) { if (string(object).compare(expected) == 0) { cout << "string(" << what << ") is '" << expected << "', as expected." << endl; return 0; } else { cerr << what << " '" << object << "' should be '" << expected << "' when cast to std::string!" << endl; return 1; } } // Compare the given string against the object when converted in several // different ways to a string. template <class T> static unsigned int test_stringization(const T& object, const char* expected, const char* what) { return test_query_insert(object, expected, what) + test_ostream_insert(object, expected, what) + test_string_operator(object, expected, what) + test_str_method(object, expected, what); } // Given a Date and a set of values we should expect to be in it, // compare its outputs against values we compute separately. static unsigned int test_date(const Date& d, int year, int month, int day) { if ( d.year() == year && d.month() == month && d.day() == day) { char ac[20]; snprintf(ac, sizeof(ac), "%04d-%02d-%02d", year, month, day); return test_stringization(d, ac, "Date"); } else { cerr << "Date '" << d << "' values should be '" << year << '-' << month << '-' << day << endl; return 1; } } // Given a Time and a set of values we should expect to be in it, // compare its outputs against values we compute separately. static unsigned int test_time(const Time& t, int hour, int minute, int second) { if ( t.hour() == hour && t.minute() == minute && t.second() == second) { char ac[20]; snprintf(ac, sizeof(ac), "%02d:%02d:%02d", hour, minute, second); return test_stringization(t, ac, "Time"); } else { cerr << "Time '" << t << "' values should be '" << hour << ':' << minute << ':' << second << endl; return 1; } } // Given a DateTime and a set of values we should expect to be in it, // compare its outputs against values we compute separately. static unsigned int test_datetime(const DateTime& dt, int year, int month, int day, int hour, int minute, int second) { return test_date(Date(dt), year, month, day) + test_time(Time(dt), hour, minute, second); } // Run tests above for the various types we support using the date and // time values given. static unsigned int test(int year, int month, int day, int hour, int minute, int second) { unsigned int failures = 0; failures += test_date(Date(year, month, day), year, month, day); failures += test_datetime( DateTime(year, month, day, hour, minute, second), year, month, day, hour, minute, second); failures += test_time(Time(hour, minute, second), hour, minute, second); return failures; } int main() { unsigned int failures = 0; #if !defined(__SUNPRO_CC) // Sun CC can't compile these tests for some reason. So, skip them. // See http://lists.mysql.com/plusplus/8164 failures += test(0, 0, 0, 0, 0, 0); failures += test(1, 2, 3, 4, 5, 6); failures += test_stringization(DateTime(), "NOW()", "DateTime"); DateTime dt; dt.year(2007); failures += test_stringization(dt, "2007-00-00 00:00:00", "DateTime"); #endif return failures; } |
Added test/insertpolicy.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 | /*********************************************************************** test/insertpolicy.cpp - Checks that the *InsertPolicy objects work as expected. Copyright (c) 2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <climits> #include <iostream> static const unsigned char nonzero = 4; template <class InsertPolicy> static bool test_policy(InsertPolicy& ip, unsigned char max, bool expected_to_fail) { unsigned char i; mysqlpp::Row dummy; for (i = 0; i < UCHAR_MAX; ++i) { if (!ip.can_add(i, dummy)) { break; } } if (expected_to_fail ? i != max : i == max) { return true; } else { std::cerr << typeid(ip).name() << '(' << int(max) << ") allowed " << int(i) << " inserts!" << std::endl; return false; } } template <class InsertPolicy> static bool test_policy(InsertPolicy& ip, unsigned char expected_allow_count) { return test_policy(ip, expected_allow_count, false) && test_policy(ip, expected_allow_count + 1, true) && test_policy(ip, expected_allow_count - 1, true) && test_policy(ip, expected_allow_count ? 0 : nonzero, true); } static bool test_row_count_nonzero() { mysqlpp::Query::RowCountInsertPolicy<> ip_nonzero(nonzero); return test_policy(ip_nonzero, nonzero); } static bool test_row_count_zero() { mysqlpp::Query::RowCountInsertPolicy<> ip_zero(0); return test_policy(ip_zero, 0); } static bool test_row_count() { return test_row_count_nonzero() && test_row_count_zero(); } int main() { try { return test_row_count() ? 0 : 1; } catch (...) { std::cerr << "Unhandled exception caught by " "test/insertpolicy!" << std::endl; return 2; } } |
Added test/inttypes.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 | /*********************************************************************** test/inttypes.cpp - Tests whether the integer typedef equivalents for SQL types in lib/sql_types.h are correct on this system. If not, you need to change either that file, lib/common.h, or both. Copyright (c) 2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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_types.h> #include <iostream> template <typename IntType> static bool test_size(const char* desc, IntType value, size_t expected_size) { size_t actual_size = sizeof(value); if (actual_size == expected_size) { return true; } else { std::cerr << desc << " is sized incorrectly on this " "platform:" << std::endl << "\t" << actual_size << " bytes, not " << expected_size << " as expected." << std::endl; return false; } } int main() { int failures = 0; failures += test_size("sql_tinyint", mysqlpp::sql_tinyint(0), 1) == false; failures += test_size("sql_tinyint_unsigned", mysqlpp::sql_tinyint_unsigned(0), 1) == false; failures += test_size("sql_smallint", mysqlpp::sql_smallint(0), 2) == false; failures += test_size("sql_smallint_unsigned", mysqlpp::sql_smallint_unsigned(0), 2) == false; failures += test_size("sql_mediumint", mysqlpp::sql_mediumint(0), 4) == false; failures += test_size("sql_mediumint_unsigned", mysqlpp::sql_mediumint_unsigned(0), 4) == false; failures += test_size("sql_int", mysqlpp::sql_int(0), 4) == false; failures += test_size("sql_int_unsigned", mysqlpp::sql_int_unsigned(0), 4) == false; failures += test_size("sql_bigint", mysqlpp::sql_bigint(0), 8) == false; failures += test_size("sql_bigint_unsigned", mysqlpp::sql_bigint_unsigned(0), 8) == false; return failures; } |
Added test/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 | /*********************************************************************** test/manip.cpp - Tests the quoting and escaping manipulators. Copyright (c) 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> #include <sstream> #include <string> template <class T> static bool is_quoted(const std::string& s, T orig_str, size_t orig_len) { return (s.length() == (orig_len + 2)) && (s.at(0) == '\'') && (s.at(orig_len + 1) == '\'') && (s.compare(1, orig_len, orig_str) == 0); } template <class T> static bool is_quoted(const std::string& s, mysqlpp::Null<T> orig_str, size_t orig_len) { return is_quoted(s, orig_str.data, orig_len); } // Stringish types should be quoted when inserted into Query when an // explicit quote manipulator is used. template <class T> static bool explicit_query_quote(T test, size_t len) { mysqlpp::Query q(0); q << mysqlpp::quote << test; if (!is_quoted(q.str(), test, len)) { std::cerr << "Explicit quote of " << typeid(test).name() << " in Query failed: " << q.str() << std::endl; return false; } mysqlpp::SQLStream s(0); s << mysqlpp::quote << test; if (is_quoted(s.str(), test, len)) { return true; } else { std::cerr << "Explicit quote of " << typeid(test).name() << " in Query failed: " << q.str() << std::endl; return false; } } // Nothing should be quoted when inserted into an ostream, even when an // explicit quote manipulator is used. The manipulators are only for // use with Query streams. template <class T> static bool no_explicit_ostream_quote(T test, size_t len) { std::ostringstream outs; outs << mysqlpp::quote << test; if (!is_quoted(outs.str(), test, len)) { return true; } else { std::cerr << "Explicit quote of " << typeid(test).name() << " in ostream erroneously honored!" << std::endl; return false; } } // Nothing should be implicitly quoted as of v3. We used to do it for // mysqlpp::String (formerly ColData) when inserted into Query, but // that's a silly edge case. The only time end-user code should be // using Strings to build queries via the Query stream interface is when // using BLOBs or when turning result set data back around in a new // query. In each case, there's no reason for String to behave // differently from std::string, which has always had to be explicitly // quoted. template <class T> static bool no_implicit_quote(T test, size_t len) { std::ostringstream outs; outs << test; if (!is_quoted(outs.str(), test, len)) { mysqlpp::Query q(0); q << test; if (is_quoted(q.str(), test, len)) { std::cerr << typeid(test).name() << " erroneously implicitly " "quoted in Query: " << outs.str() << std::endl; return false; } mysqlpp::SQLStream s(0); s << test; if (!is_quoted(s.str(), test, len)) { return true; } else { std::cerr << typeid(test).name() << " erroneously implicitly " "quoted in Query: " << outs.str() << std::endl; return false; } } else { std::cerr << typeid(test).name() << " erroneously implicitly " "quoted in ostringstream: " << outs.str() << std::endl; return false; } } // Run all tests above for the given type template <class T> static bool test(T test, size_t len) { return explicit_query_quote(test, len) && no_explicit_ostream_quote(test, len) && no_implicit_quote(test, len); } int main() { char s[] = "Doodle me, James, doodle me!"; const size_t len = strlen(s); int failures = 0; failures += test(s, len) == false; failures += test(static_cast<char*>(s), len) == false; failures += test(static_cast<const char*>(s), len) == false; failures += test(std::string(s), len) == false; failures += test(mysqlpp::SQLTypeAdapter(s), len) == false; failures += test(mysqlpp::Null<std::string>(s), len) == false; return failures; } |
Added test/null_comparison.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 | /*********************************************************************** test/null_comparison.cpp - Tests that Null<T> and null_type comparison operators and SSQLS comparison functions work correctly. Copyright (c) 2008-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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> #define MYSQLPP_ALLOW_SSQLS_V1 // suppress deprecation warning #include <ssqls.h> #include <iostream> sql_create_1(ssqls, 1, 0, mysqlpp::Null<int>, a_column) int main() { mysqlpp::Null<int> null_int = mysqlpp::null; mysqlpp::Null<int> non_null_int = 42; if ( !(null_int == non_null_int) && (null_int != non_null_int) && (null_int < non_null_int) && !(non_null_int == null_int) && (non_null_int != null_int) && !(non_null_int < null_int) && (null_int == mysqlpp::null) && !(null_int != mysqlpp::null) && (non_null_int != mysqlpp::null) && !(non_null_int == mysqlpp::null) && (mysqlpp::sql_cmp(null_int, null_int) == 0) && (mysqlpp::sql_cmp(null_int, non_null_int) < 0) && (mysqlpp::sql_cmp(non_null_int, null_int) > 0)) { ssqls foo(null_int), bar(non_null_int); if ((foo < bar) && (foo != bar) && !(bar < foo) && !(foo == bar)) { return 0; } else { std::cerr << "SSQLS comparison gave unexpected result" << std::endl; return 1; } } else { std::cerr << "Null comparison gave unexpected result" << std::endl; return 1; } } |
Added test/null_uniqueness.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 | /*********************************************************************** test/null_uniqueness.cpp - Code for checking that null_type cannot be converted to anything else. Because it triggers a compile-time check, it can't be included in the test suite. You have to just try building it. Comment out the assignment to int to check that the return statement also triggers the compile-time check. Copyright (c) 2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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> int main() { mysqlpp::Null<int> ni = mysqlpp::null; int this_should_not_even_compile = mysqlpp::null; return ni; // neither should this } |
Added test/qssqls.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 | /*********************************************************************** test/qssqls.cpp - Tests SQL query creation from SSQLS in Query. Copyright (c) 2008-2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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> #define MYSQLPP_ALLOW_SSQLS_V1 // suppress deprecation warning #include <ssqls.h> #include <iostream> using namespace mysqlpp; using namespace std; sql_create_19(test, 19, 0, sql_tinyint, tinyint_v, sql_tinyint_unsigned, tinyint_unsigned_v, sql_smallint, smallint_v, sql_smallint_unsigned, smallint_unsigned_v, sql_int, int_v, sql_int_unsigned, int_unsigned_v, sql_mediumint, mediumint_v, sql_mediumint_unsigned, mediumint_unsigned_v, sql_bigint, bigint_v, sql_bigint_unsigned, bigint_unsigned_v, sql_float, float_v, sql_double, double_v, sql_decimal, decimal_v, sql_bool, bool_v, sql_date, date_v, sql_time, time_v, sql_datetime, datetime_v, sql_char, char_v, // only need one stringish type... sql_blob, blob_v) // ...and one blob type; they're all // the same under the hood in MySQL++ int main() { Query q(0); // don't pass 0 for conn parameter in real code test empty(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, Date(), Time(), DateTime(), "", sql_blob()); test filled(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.0, 12.0, 13.0, bool(14), Date("1515-15-15"), Time("16:16:16"), DateTime("1717-17-17 17:17:17"), "18", sql_blob("1\09", 3)); cout << q.insert(empty) << endl << endl; cout << q.insert(filled) << endl << endl; cout << q.replace(empty) << endl << endl; cout << q.replace(filled) << endl << endl; cout << q.update(filled, empty) << endl << endl; return 0; } |
Added test/qstream.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 | /*********************************************************************** test/qstream.cpp - Tests insertion of all officially-supported data types into a Query stream, plus some that aren't official. Failure is defined as an exception being thrown for any one of these. Copyright (c) 2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> using namespace mysqlpp; int main() { try { // If you're reading this for implicit recommendations of good // code style, please ignore the hack-job on the following line. mysqlpp::Query q = mysqlpp::Connection().query(); // Throw everything we can think of at Query's stream interface. // Don't do this in real code, either. q << sql_tinyint(0) << sql_tinyint_unsigned(0) << sql_smallint(0) << sql_smallint_unsigned(0) << sql_mediumint(0) << sql_mediumint_unsigned(0) << sql_int(0) << sql_int_unsigned(0) << long(0) << sql_bigint(0) << sql_bigint_unsigned(0) << longlong(0) << sql_int1(0) << sql_int2(0) << sql_int3(0) << sql_int4(0) << sql_int8(0) << sql_middleint(0) << sql_float(0) << sql_double(0) << sql_decimal(0) << sql_numeric(0) << sql_fixed(0) << sql_float4(0) << sql_float8(0) << sql_bool(false) << sql_boolean(false) << bool(false) << sql_enum() << sql_char() << sql_varchar() << sql_long_varchar() << sql_character_varying() << sql_long() << sql_tinytext() << sql_text() << sql_mediumtext() << sql_longtext() << sql_blob() << sql_tinyblob() << sql_mediumblob() << sql_longblob() << sql_long_varbinary() << sql_date() << sql_time() << sql_datetime() << sql_timestamp() << sql_set(); std::cout << q << std::endl; return 0; } catch (const mysqlpp::TypeLookupFailed& e) { std::cerr << "Query stream insert failed: " << e.what() << std::endl; return 1; } catch (const std::exception& e) { std::cerr << "Unexpected exception: " << e.what() << std::endl; return 1; } } |
Added test/query_copy.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 | /*********************************************************************** test/query_copy.cpp - Tests SQL query copies, to ensure that we copy it deeply enough. Copyright (c) 2009 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> using namespace mysqlpp; using namespace std; static bool test_parm(const char* testname, Query& q1, Query q2, const char* parm) { string s1 = q1.str(parm); string s2 = q2.str(parm); if (s1.compare(s2) == 0) { return true; } else { std::cerr << "TEST " << testname << " failed: " << "s1('" << s1 << "') != " << "s2('" << s2 << "')!" << std::endl; return false; } } static bool test_plain(const char* testname, Query& q1, Query q2) { if (q1.str().compare(q2.str()) == 0) { return true; } else { std::cerr << "TEST " << testname << " failed: " << "q1('" << q1.str() << "') != " << "q2('" << q2.str() << "')!" << std::endl; return false; } } int main() { try { Query orig1(0); // don't pass 0 for conn parameter in real code orig1 << "raw string insert method test"; Query copy1(orig1); Query copy2(0); copy2 = orig1; Query orig2(0, false, "string ctor test"); // don't do this, either Query copy3(orig2); Query copy4(0); copy4 = orig2; Query orig3(0, false, "template %0 test"); orig3.parse(); Query copy5(orig3); Query copy6(0); copy6 = orig3; if ( test_plain("1a", orig1, copy1) && test_plain("1b", orig1, copy2) && test_plain("2a", orig2, copy3) && test_plain("2b", orig2, copy4) && test_parm("3a", orig3, copy5, "query") && test_parm("3b", orig3, copy6, "query")) { return 0; } } catch (const mysqlpp::Exception& e) { std::cerr << "Query copy test failed: " << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << "Unexpected exception: " << e.what() << std::endl; } return 1; } |
Added test/sqlstream.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 | /*********************************************************************** test/sqlstream.cpp - Tests SQLStream class, which is handled by the stream manipulators just like Query. Copyright (c) 2008 by AboveNet, 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> #define MYSQLPP_ALLOW_SSQLS_V1 // suppress deprecation warning #include <ssqls.h> #include <sqlstream.h> #include <iostream> using namespace mysqlpp; using namespace std; sql_create_23(test, 23, 0, sql_tinyint, tinyint_v, sql_tinyint_unsigned, tinyint_unsigned_v, sql_smallint, smallint_v, sql_smallint_unsigned, smallint_unsigned_v, sql_int, int_v, sql_int_unsigned, int_unsigned_v, sql_mediumint, mediumint_v, sql_mediumint_unsigned, mediumint_unsigned_v, sql_bigint, bigint_v, sql_bigint_unsigned, bigint_unsigned_v, sql_float, float_v, sql_double, double_v, sql_decimal, decimal_v, sql_bool, bool_v, sql_date, date_v, sql_time, time_v, sql_datetime, datetime_v, sql_char, char_v, sql_varchar, varchar_v, sql_tinytext, tinytext_v, sql_text, text_v, sql_mediumtext, mediumtext_v, sql_longtext, longtext_v) int main() { SQLStream sqls(0); // don't do this in real code test empty(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, Date(), Time(), DateTime(),"","","","","",""); test filled(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.0, 12.0, 13.0, bool(14), Date("1515-15-15"), Time("16:16:16"), DateTime("1717-17-17 17:17:17"),"18","19","20","21","22","23"); sqls << "INSERT INTO " << filled.table() << " (" << filled.field_list() << ") VALUES (" << filled.value_list() << ")"; cout << sqls.str() << endl; sqls.str(""); sqls << "INSERT INTO " << empty.table() << " (" << empty.field_list() << ") VALUES (" << empty.value_list() << ")"; cout << sqls.str() << endl; return 0; } |
Added test/ssqls2.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 | /*********************************************************************** test/ssqls2.cpp - Tests the SSQLS v2 mechanism Copyright (c) 2009 by Warren Young. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 "../ssx/parsev2.h" #include <mysql++.h> #include <ssqls2.h> #include <iostream> using namespace std; // Check that we can create a custom SSQLS v2 subclass by hand. Tests // for unexpected changes in SsqlsBase definition. class TestSubclass : public mysqlpp::SsqlsBase { public: TestSubclass() : mysqlpp::SsqlsBase() { } bool create_table(mysqlpp::Connection* conn = 0) const { (void)conn; return false; } std::ostream& equal_list(std::ostream& os, FieldSubset fs = fs_set) const { (void)fs; return os; } std::ostream& name_list(std::ostream& os, FieldSubset fs = fs_set) const { (void)fs; return os; } bool populated(FieldSubset fs = fs_all) const { (void)fs; return false; } std::ostream& value_list(std::ostream& os, FieldSubset fs = fs_set) const { (void)fs; return os; } }; // Test a single string to ParseV2::Field::Type value conversion static bool Test(const char* input_type, const ParseV2::Field::Type& expected_value) { ParseV2::Field::Type actual_value(input_type); if (actual_value == expected_value) { return true; } else { std::cerr << '"' << input_type << "\" converted to " << int(actual_value) << " not " << int(expected_value) << " as expected!" << std::endl; return false; } } // Test as many string to ParseV2::Field::Type value conversions as we // expect the smart enum to support. static bool TestFieldTypeConversions() { return // First, test all the known "sane" inputs Test("bigblob", ParseV2::Field::Type::ft_blob) && Test("bigint", ParseV2::Field::Type::ft_bigint) && Test("bigtext", ParseV2::Field::Type::ft_string) && Test("blob", ParseV2::Field::Type::ft_blob) && Test("bool", ParseV2::Field::Type::ft_tinyint) && Test("boolean", ParseV2::Field::Type::ft_tinyint) && Test("char", ParseV2::Field::Type::ft_string) && Test("date", ParseV2::Field::Type::ft_date) && Test("datetime", ParseV2::Field::Type::ft_datetime) && Test("decimal", ParseV2::Field::Type::ft_double) && Test("double", ParseV2::Field::Type::ft_double) && Test("enum", ParseV2::Field::Type::ft_string) && Test("fixed", ParseV2::Field::Type::ft_double) && Test("float", ParseV2::Field::Type::ft_float) && Test("float4", ParseV2::Field::Type::ft_float) && Test("float8", ParseV2::Field::Type::ft_float) && Test("int", ParseV2::Field::Type::ft_mediumint) && Test("int1", ParseV2::Field::Type::ft_tinyint) && Test("int2", ParseV2::Field::Type::ft_smallint) && Test("int3", ParseV2::Field::Type::ft_mediumint) && Test("int4", ParseV2::Field::Type::ft_mediumint) && Test("int8", ParseV2::Field::Type::ft_bigint) && Test("mediumblob", ParseV2::Field::Type::ft_blob) && Test("mediumint", ParseV2::Field::Type::ft_mediumint) && Test("mediumtext", ParseV2::Field::Type::ft_string) && Test("numeric", ParseV2::Field::Type::ft_double) && Test("set", ParseV2::Field::Type::ft_set) && Test("smallblob", ParseV2::Field::Type::ft_blob) && Test("smallint", ParseV2::Field::Type::ft_smallint) && Test("smalltext", ParseV2::Field::Type::ft_string) && Test("text", ParseV2::Field::Type::ft_string) && Test("time", ParseV2::Field::Type::ft_time) && Test("timestamp", ParseV2::Field::Type::ft_datetime) && Test("tinyblob", ParseV2::Field::Type::ft_blob) && Test("tinyint", ParseV2::Field::Type::ft_tinyint) && Test("tinytext", ParseV2::Field::Type::ft_string) && Test("varbinary", ParseV2::Field::Type::ft_blob) && Test("varchar", ParseV2::Field::Type::ft_string) && // Test that it's properly case-insensitive Test("Numeric", ParseV2::Field::Type::ft_double) && Test("sEt", ParseV2::Field::Type::ft_set) && Test("SMALLBLOB", ParseV2::Field::Type::ft_blob) && // Test that mildly bogus conversions are handled sanely Test("char(8)", ParseV2::Field::Type::ft_string) && Test("decimal(16)", ParseV2::Field::Type::ft_double) && Test("int5", ParseV2::Field::Type::ft_mediumint) && Test("varchar(32)", ParseV2::Field::Type::ft_string) && // Test that truly bogus stuff gets treated as stringish Test("varwhatsit(64)", ParseV2::Field::Type::ft_string) && Test("klH54%KJgh^7hh4jvwtt", ParseV2::Field::Type::ft_string) && true; } int main() { // Force instantiation of custom subclass TestSubclass tsc; return TestFieldTypeConversions() ? 0 : 1; } |
Added test/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 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 | /*********************************************************************** test/string.cpp - Tests the behavior of mysqlpp::String, particularly its data conversion methods. Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> // Does an equality comparison on the value, forcing the string to // convert itself to T on the way. Note that we do this test in terms // of greater and less than to avoid pedantic GCC warnings for the // floating point type tests. template <typename T> static bool test_equality(const mysqlpp::String& s, T value) { T converted = s.conv(value); if ((value < converted) || (value > converted)) { std::cerr << "Type conversion to " << typeid(T).name() << " failed: \"" << s << "\" != \"" << value << "\"." << std::endl; return false; } else { return true; } } // Check that we can convert strings with decimals in them to native // floating-point values, regardless of locale. static bool test_float_conversion() { // This stuff should just work if (!test_equality(mysqlpp::String("123.00"), 123)) return false; if (!test_equality(mysqlpp::String("123."), 123)) return false; // This is trickier: MySQL ignores the system locale when it comes // to decimal separators, always using '.', so ensure the conversion // stuff in MySQL++ does the right thing regardless. Test against // this system's current locale, an arbitrary European one where ',' // is the decimal separator, and the "C" locale where it's '.'. if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false; std::locale old_locale = std::locale::global(std::locale::classic()); if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false; try { std::locale::global(std::locale("de_DE")); if (!test_equality(mysqlpp::String("621.200"), 621.2)) return false; } catch (std::runtime_error& e) { std::cerr << "WARNING: skipping European locale string " "conversion test:" << std::endl; std::cerr << "\t" << e.what() << std::endl; } std::locale::global(old_locale); // Check that we choke on silly float-like values try { if (test_equality(mysqlpp::String("621.20.0"), 621.2)) { std::cerr << "Quasi-FP with two decimal points " "converting without error!" << std::endl; } return false; } catch (const mysqlpp::BadConversion&) { return true; } } // Tries to convert the given string to an int. Returns false if we got // a BadConversion exception and didn't expect it, or didn't get one we // expected. Returns false on all other exceptions regardless. static bool test_int_conversion(const mysqlpp::String& s, bool throw_expected) { // Try the conversion bool conv_threw = false; try { int converted = s; (void)converted; // pedantic warning squisher } catch (const mysqlpp::BadConversion&) { conv_threw = true; } catch (const std::exception& e) { std::cerr << "Unexpected " << typeid(e).name() << " exception in test_int_conv: " << e.what() << std::endl; return false; } catch (...) { std::cerr << "Like, totally bogus exception in test_int_conv, " "man!" << std::endl; return false; } // Did it do what we expected? if (throw_expected == conv_threw) { return true; } else { std::cerr << "Conversion of \"" << s << "\" to int " << (conv_threw ? "did not throw" : "threw") << "; " << (throw_expected ? "did not expect" : "expected") << " it to." << std::endl; return false; } } // Checks that String's null comparison methods work right static bool test_null() { mysqlpp::String not_null("", mysqlpp::mysql_type_info::string_type, false); mysqlpp::String is_null("", mysqlpp::mysql_type_info::string_type, true); if (not_null.is_null() == true) { std::cerr << "not_null.is_null() == true!" << std::endl; return false; } else if (not_null == mysqlpp::null) { std::cerr << "not_null == mysqlpp:null!" << std::endl; return false; } else if (is_null.is_null() == false) { std::cerr << "is_null.is_null() == false!" << std::endl; return false; } else if (is_null != mysqlpp::null) { std::cerr << "is_null != mysqlpp:null!" << std::endl; return false; } else { return true; } } // Ensures numeric conversions of many different types get handled // correctly. static bool test_numeric(const mysqlpp::String& s, int value) { return test_equality(s, static_cast<signed char>(value)) && test_equality(s, static_cast<unsigned char>(value)) && test_equality(s, static_cast<signed short>(value)) && test_equality(s, static_cast<unsigned short>(value)) && test_equality(s, static_cast<signed int>(value)) && test_equality(s, static_cast<unsigned int>(value)) && test_equality(s, static_cast<signed long>(value)) && test_equality(s, static_cast<unsigned long>(value)) && #if !defined(NO_LONG_LONGS) test_equality(s, static_cast<mysqlpp::longlong>(value)) && test_equality(s, static_cast<mysqlpp::ulonglong>(value)) && #endif test_equality(s, static_cast<float>(value)) && test_equality(s, static_cast<double>(value)); } static bool test_quote_q(const mysqlpp::String& s, bool expected) { if (s.quote_q() == expected) { return true; } else { std::cerr << s.type().name() << " should" << (expected ? "" : " NOT") << " be quoted." << std::endl; return false; } } // Similar to test_equality, but only works with std::string // comparisons, which uses String::operator ==() static bool test_string_equality(const mysqlpp::String& s, std::string value) { if (s == value) { if (s != value) { std::cerr << "String(\"" << s << "\") != std::string(\"" << value << "\"), case 2!" << std::endl; return false; } else { return true; } } else { std::cerr << "String(\"" << s << "\") != std::string(\"" << value << "\"), case 1!" << std::endl; return false; } } // Same as above, but for two String objects static bool test_string_equality(const mysqlpp::String& s1, const mysqlpp::String s2) { if (s1 == s2) { return true; } else { std::cerr << "String(\"" << s1 << "\") != String(\"" << s2 << "\"), but should be equal!" << std::endl; return false; } } // Inverse of above. static bool test_string_inequality(const mysqlpp::String& s1, const mysqlpp::String& s2) { if (s1 != s2) { return true; } else { std::cerr << "String(\"" << s1 << "\") == String(\"" << s2 << "\") but shouldn't be!" << std::endl; return false; } } int main(int, char* argv[]) { try { int failures = 0; mysqlpp::String definit; mysqlpp::String empty(""); mysqlpp::String zero("0"); mysqlpp::String nonzero("42"); mysqlpp::String intable1("42."); mysqlpp::String intable2("42.0"); mysqlpp::String nonint("42.1"); failures += test_equality(definit, mysqlpp::Date()) == false; failures += test_equality(definit, mysqlpp::DateTime(0, 0, 0, 0, 0, 0)) == false; failures += test_equality(definit, mysqlpp::Time()) == false; failures += test_equality(definit, false) == false; failures += test_equality(nonzero, true) == false; failures += test_numeric(definit, 0) == false; failures += test_numeric(zero, 0) == false; failures += test_numeric(nonzero, 42) == false; failures += test_quote_q(definit, true) == false; failures += test_quote_q(mysqlpp::String("1", typeid(int)), false) == false; failures += test_float_conversion() == false; failures += test_float_conversion() == false; failures += test_int_conversion(definit, false) == false; failures += test_int_conversion(zero, false) == false; failures += test_int_conversion(nonzero, false) == false; failures += test_int_conversion(intable1, false) == false; failures += test_int_conversion(intable2, false) == false; failures += test_int_conversion(nonint, true) == false; failures += test_null() == false; failures += test_string_equality(definit, empty) == false; failures += test_string_equality(empty, definit) == false; failures += test_string_equality(definit, "") == false; failures += test_string_equality(zero, "0") == false; failures += test_string_inequality(definit, zero) == false; failures += test_string_inequality(zero, definit) == false; failures += test_string_inequality(empty, nonzero) == false; return failures; } catch (mysqlpp::Exception& e) { std::cerr << "Unexpected MySQL++ exception caught in " << argv[0] << ": " << e.what() << std::endl; return 1; } catch (std::exception& e) { std::cerr << "Unexpected C++ exception caught in " << argv[0] << ": " << e.what() << std::endl; return 1; } } |
Added test/tcp.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 | /*********************************************************************** test/tcp.cpp - Tests the address parser/verifier in TCPConnection. Copyright (c) 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <exceptions.h> #include <tcp_connection.h> #include <iostream> #include <sstream> static void test(const char* addr_svc, unsigned int port, const char* exp_addr, unsigned int exp_port) { std::string addr(addr_svc), error; mysqlpp::TCPConnection::parse_address(addr, port, error); if (error.size()) { throw mysqlpp::SelfTestFailed("TCP address parse error: " + error); } else if (addr.compare(exp_addr) != 0) { std::ostringstream outs; outs << "TCP address parse mismatch: '" << addr << "' != '" << exp_addr << "'"; throw mysqlpp::SelfTestFailed(outs.str()); } else if (port != exp_port) { std::ostringstream outs; outs << "TCP port parse mismatch: '" << port << "' != '" << exp_port << "'"; throw mysqlpp::SelfTestFailed(outs.str()); } } static void fail(const char* addr_svc, unsigned int port, const char* exp_addr, unsigned int exp_port) { try { test(addr_svc, port, exp_addr, exp_port); } catch (...) { return; // eat expected error } std::ostringstream outs; outs << "'" << addr_svc << "' == ('" << exp_addr << "', " << exp_port << ") but should not."; throw mysqlpp::SelfTestFailed(outs.str()); } int main() { try { // Domain name and IPv4 literal tests test(":", 0, "", 0); test("1.2.3.4", 0, "1.2.3.4", 0); test("1.2.3.4:", 0, "1.2.3.4", 0); test("1.2.3.4:567", 0, "1.2.3.4", 567); test("1.2.3.4", 890, "1.2.3.4", 890); test("1.2.3.4:telnet", 0, "1.2.3.4", 23); test("a.b.com", 0, "a.b.com", 0); test("a.b.com", 987, "a.b.com", 987); fail("@", 0, "@", 0); fail("::", 0, "", 0); fail(":", 0, "1.2.3.4", 45); fail("a.b.com::", 0, "a.b.com", 0); fail("a.b:com:1", 0, "a.b.com", 1); // IPv6 literal tests test("[]:123", 0, "", 123); test("[::]:telnet", 0, "::", 23); std::cout << "TCP address parsing passed." << std::endl; return 0; } catch (mysqlpp::SelfTestFailed& e) { std::cerr << "TCP address parse error: " << e.what() << std::endl; return 1; } catch (std::exception& e) { std::cerr << "Unexpected test failure: " << e.what() << std::endl; return 2; } } |
Added test/uds.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 | /*********************************************************************** test/uds.cpp - Tests the Unix domain socket verifier in UnixDomainSocketConnection. This test always succeeds on Windows! Copyright (c) 2007-2008 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <connection.h> #include <exceptions.h> #include <iostream> #include <sstream> #include <string> #if !defined(MYSQLPP_PLATFORM_WINDOWS) #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/un.h> #if !defined(AF_LOCAL) # define AF_LOCAL AF_UNIX #endif #include <errno.h> #include <string.h> static const char* success_path = "test_uds_success.sock"; static const char* failure_path = "test_uds_failure.sock"; static int make_socket(const char* path, mode_t mode) { // Just in case a socket with this name exists already, try to // remove it. Only a failure if it exists and we can't remove it. if ((unlink(path) < 0) && (errno != ENOENT)) { return -1; } // Create the domain socket int fd = socket(AF_LOCAL, SOCK_STREAM, 0); if (fd < 0) { return -1; } // Bind the socket to the named file struct sockaddr_un saun; memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_LOCAL; strncpy(saun.sun_path, path, sizeof(saun.sun_path)); saun.sun_path[sizeof(saun.sun_path) - 1] = '\0'; if (bind(fd, reinterpret_cast<sockaddr*>(&saun), sizeof(saun)) < 0) { return -1; } // Change the socket's mode as requested if (chmod(path, mode) < 0) { return -1; } return fd; } static void test_success() { std::string error; int fd = make_socket(success_path, S_IREAD | S_IWRITE); if (fd >= 0) { bool fail = !mysqlpp::UnixDomainSocketConnection::is_socket( success_path, &error); if (fail) { throw mysqlpp::SelfTestFailed(error); } } else { std::ostringstream outs; outs << "Failed to create test domain socket: " << strerror(errno); throw mysqlpp::SelfTestFailed(outs.str()); } } static void test_failure() { int fd = make_socket(failure_path, S_IREAD); if (fd < 0) { std::ostringstream outs; outs << "Failed to create test domain socket: " << strerror(errno); throw mysqlpp::SelfTestFailed(outs.str()); } if (mysqlpp::UnixDomainSocketConnection::is_socket(failure_path)) { throw mysqlpp::SelfTestFailed("Failed to fail on read-only socket"); } else if (mysqlpp::UnixDomainSocketConnection::is_socket( "BogusBogus.sock")) { throw mysqlpp::SelfTestFailed("Failed to fail on bad file name"); } else { close(fd); unlink(failure_path); fd = creat(failure_path, S_IREAD | S_IWRITE); bool success = mysqlpp::UnixDomainSocketConnection::is_socket( failure_path); if (success) { throw mysqlpp::SelfTestFailed("Failed to fail on non-socket"); } } } #endif int main() { #if defined(MYSQLPP_PLATFORM_WINDOWS) // Test not appropriate to this platform. Always succeed. return 0; #else try { test_success(); unlink(success_path); test_failure(); unlink(failure_path); return 0; } catch (mysqlpp::SelfTestFailed& e) { std::cerr << "TCP address parse error: " << e.what() << std::endl; return 1; } catch (std::exception& e) { std::cerr << "Unexpected test failure: " << e.what() << std::endl; return 2; } #endif } |
Added test/wnp.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 | /*********************************************************************** test/wnp.cpp - Tests WindowsNamedPipeConnection::is_wnp(). This test can only fail on Windows! It succeeds when built for anything else. Copyright (c) 2007 by Educational Technology Resources, Inc. Others may also hold copyrights on code in this file. See the CREDITS.txt 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 <iostream> #include <sstream> int main() { #if defined(MYSQLPP_PLATFORM_WINDOWS) if (!mysqlpp::WindowsNamedPipeConnection::is_wnp(".")) { std::cerr << "Failed to identify Windows named pipe" << std::endl; } else if (mysqlpp::WindowsNamedPipeConnection::is_wnp("bogus")) { std::cerr << "Failed to fail for bogus named pipe" << std::endl; } else if (mysqlpp::WindowsNamedPipeConnection::is_wnp(0)) { std::cerr << "Failed to fail for null named pipe" << std::endl; } else { return 0; } return 1; #else return 0; #endif } |
Added tools/tarballs-to-fossil.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #!/bin/bash ignores="$(tr '\n' ',' < ../tb-ignore-glob)" rdir=~/tangentsoft.com/mysql++/releases set -e ls $rdir/*.tar.gz | ggrep -Po '\d[\d.]+\d[.a-f]{0,2}' | sed -e 's/\.$//' | gsort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | while read ver do f=$(echo $rdir/*-${ver}.tar.gz) echo -e "\n----------------------------------------------------------" echo -e "Processing MySQL++ v$ver, $(basename $f)...\n" find . -type f -not -name .fslckout -delete find . -type d -delete if gtar -x --strip-components=1 -f "$f" then fossil addremove --ignore "$ignores" if [ -e ChangeLog ] then newest=ChangeLog else newest=$(find . -type f -print0 | xargs -0 ls -t | head -n 2 | tail -1) fi mtime=$(date -u -r "$newest" +%FT%TZ) echo "Checking in MySQL++ v$ver, mtime=$mtime..." fossil ci \ --comment "Version $ver" \ --date-override $mtime \ --no-warnings \ --tag "v$ver" fi done fossil ui |
Added tools/tb-ignore-glob.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | *~ */#* *.dsp *.dsw *.log *.old *.svn/* *.vcproj abi.xml acconfig.h acinclude.m4 aclocal.m4 bk.deps config.guess config.h config.status config.sub Configure configure config/libtool.m4 config/lt*.m4 devel/* depcomp doc/*.pdf doc/*.tex doc/CVS/* doc/html/* doc/html.sty doc/Makefile.in doc/Makefile.org doc/man-html/* doc/man-text/* doc/manual.aux doc/manual.dvi doc/manual.ps doc/manual.ps.gz doc/manual.toc doc/refman/html/* doc/userman/*.txt doc/userman/html/* examples/*.bpg examples/*.bpf examples/*.bpr examples/*.dsp examples/*.dsw examples/*.vcproj examples/Makefile.in html.sty install.hta install-sh lib/Doxyfile lib/mysql++.h libtool ltconfig ltmain.sh macros/Makefile.in Makefile Makefile.in man-html/* man-text/* manual.aux manual.dvi manual.tex manual.toc missing mkinstalldirs mysql-config mysql++-config.hh mysql++-int/*.gif mysql++-int/gifs.db mysql++-int/less mysql++-int/libmysql++.so mysql++.xcodeproj/* mysql++.spec sqlplusint/*.bpg sqlplusint/*.bpf sqlplusint/*.bpr sqlplusint/*.flt sqlplusint/*.gif sqlplusint/*.plt sqlplusint/bad_query.hh sqlplusint/custom*.hh sqlplusint/doc-fix.pl sqlplusint/doc-trim.pl sqlplusint/doc.tex sqlplusint/doc.tex.tmpl sqlplusint/headers sqlplusint/includes.pl sqlplusint/gifs.db sqlplusint/less sqlplusint/stamp-h2 sqlplusint/stamp-h2.in sqlplusint/undef_short ssx/Doxyfile stamp-h stamp-h.in stamp-h1 stamp-h1.in vc2*/* version |
Added version.in.
> > | 1 2 | #!/bin/sh echo @MYSQLPP_VERSION_MAJOR@.@MYSQLPP_VERSION_MINOR@.@MYSQLPP_VERSION_BUGFIX@ |