Author: wyoung
Date: Sat Mar 17 07:02:54 2007
New Revision: 1447
URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1447&view=rev
Log:
- resetdb now creates a second table, called images, used for testing
BLOB support
- load_file example now takes the standard command line argument format
plus one additional trailing argument, being the name of a file which
data it loads into the new table
- Added examples/logo.jpg for sample data to test with. Also, it's
preeeetttyyy.
Added:
trunk/examples/logo.jpg (with props)
Modified:
trunk/Wishlist
trunk/examples/load_file.cpp
trunk/examples/resetdb.cpp
trunk/examples/util.cpp
trunk/examples/util.h
trunk/mysql++.bkl
Modified: trunk/Wishlist
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=1447&r1=1446&r2=1447&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Sat Mar 17 07:02:54 2007
@@ -32,9 +32,6 @@
duplicating the existing type-specific manipulator functions,
and wrapping the types in Null<>.
- o Update examples/cgi_image and examples/load_file to use new
- binary-aware ColData, const_string and Query classes.
-
o Check that SSQLS works with BLOB now that ColData, const_string
and Query classes cope with embedded nulls. If not, fix.
@@ -43,20 +40,9 @@
that can have nulls, and it has the real data length at hand,
change it to use the explicit length ColData ctor.
- o Have resetdb create a second table containing a BLOB column
- that load_file and cgi_image can use.
-
- Rework load_image to take the standard command line
- parameters, and load a JPEG or something into the BLOB table.
- Include a suitable JPEG with the distribution. (A cheesy
- Photoshopped "MySQL++ Rocks!" thing should suffice.)
-
- Rework cgi_image so that you can drop it into a cgi-image
+ o Rework cgi_image so that you can drop it into a cgi-bin
directory and immediately use it to query the database and
- return the image data in CGI format.
-
- Don't forget to write an example showing how to use these
- new mechanisms.
+ return image data loaded by load_file in CGI format.
v2.4 Plan
Modified: trunk/examples/load_file.cpp
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/load_file.cpp?rev=1447&r1=1446&r2=1447&view=diff
==============================================================================
--- trunk/examples/load_file.cpp (original)
+++ trunk/examples/load_file.cpp Sat Mar 17 07:02:54 2007
@@ -25,64 +25,79 @@
USA
***********************************************************************/
+#include "util.h"
+
#include <mysql++.h>
-#include <sys/stat.h>
-
#include <fstream>
-
-#include <stdlib.h>
using namespace std;
using namespace mysqlpp;
-const char MY_DATABASE[] = "telcent";
-const char MY_TABLE[] = "fax";
-const char MY_HOST[] = "localhost";
-const char MY_USER[] = "root";
-const char MY_PASSWORD[] = "";
-const char MY_FIELD[] = "fax"; // BLOB field
+static bool
+is_jpeg(const unsigned char* img_data)
+{
+ return (img_data[0] == 0xFF) && (img_data[1] == 0xD8) &&
+ ((memcmp(img_data + 6, "JFIF", 4) == 0) ||
+ (memcmp(img_data + 6, "Exif", 4) == 0));
+}
+
int
main(int argc, char *argv[])
{
- if (argc < 2) {
- cerr << "Usage : load_file full_file_path" << endl << endl;
- return -1;
+ // Assume that the last command line argument is a file. Try to
+ // read that file's data into img_data, and check it to see if it
+ // appears to be a JPEG file. Bail otherwise.
+ string img_data;
+ if ((argc > 1) && (argv[1][0] != '-')) {
+ ifstream img_file(argv[argc - 1], ios::ate);
+ if (img_file) {
+ size_t img_size = img_file.tellg();
+ if (img_size > 10) {
+ img_file.seekg(0, ios::beg);
+ unsigned char* img_buffer = new unsigned
char[img_size];
+ img_file.read((char*)img_buffer, img_size);
+ if (is_jpeg(img_buffer)) {
+ img_data.assign((char*)img_buffer,
img_size);
+ }
+ else {
+ cerr << "File does not appear to be a
JPEG!" << endl;
+ }
+ delete[] img_buffer;
+ }
+ else {
+ cerr << "File is too short to be a JPEG!" <<
endl;
+ }
+ }
}
+ if (img_data.empty()) {
+ print_usage(argv[0], "[jpeg_file]");
+ return 1;
+ }
+ --argc; // pop filename argument off end of list
- Connection con(use_exceptions);
try {
- con.connect(MY_DATABASE, MY_HOST, MY_USER, MY_PASSWORD);
+ // Establish the connection to the database server.
+ mysqlpp::Connection con(mysqlpp::use_exceptions);
+ if (!connect_to_db(argc, argv, con)) {
+ return 1;
+ }
+
+ // Insert image data into the BLOB column in the images table.
+ // We're inserting it as an std::string instead of using the raw
+ // data buffer allocated above because we don't want the data
+ // treated as a C string, which would truncate the data at the
+ // first null character.
Query query = con.query();
- ifstream In(argv[1], ios::in | ios::binary);
- if (In) {
- struct stat for_len;
- if (stat(argv[1], &for_len) < 0) {
- cerr << "stat() failed for " << argv[1] << '!'
<< endl;
- return -1;
- }
+ query << "INSERT INTO images (data) VALUES(\"" <<
+ mysqlpp::escape << img_data << "\")";
+ ResNSel res = query.execute();
- unsigned int blen = for_len.st_size;
- if (blen == 0) {
- cerr << "Sorry, " << argv[1] << " is empty; I
won't "
- "insert such a thing." << endl;
- return -1;
- }
-
- char* read_buffer = new char[blen];
- In.read(read_buffer, blen);
- string fill(read_buffer, blen);
- ostringstream strbuf;
- strbuf << "INSERT INTO " << MY_TABLE << " (" <<
MY_FIELD <<
- ") VALUES(\"" << mysqlpp::escape <<
fill << "\")" <<
- ends;
- query.exec(strbuf.str());
- delete[] read_buffer;
- }
- else {
- cerr << "Failed to open " << argv[1] << '.' << endl;
- }
+ // If we get here, insertion succeeded
+ cout << "Inserted \"" << argv[argc] <<
+ "\" into images table, " << img_data.size() <<
+ " bytes, ID " << res.insert_id << endl;
}
catch (const BadQuery& er) {
// Handle any query errors
Added: trunk/examples/logo.jpg
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/logo.jpg?rev=1447&view=auto
==============================================================================
Binary file - no diff available.
Propchange: trunk/examples/logo.jpg
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: trunk/examples/resetdb.cpp
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/resetdb.cpp?rev=1447&r1=1446&r2=1447&view=diff
==============================================================================
--- trunk/examples/resetdb.cpp (original)
+++ trunk/examples/resetdb.cpp Sat Mar 17 07:02:54 2007
@@ -52,7 +52,9 @@
mysqlpp::Connection con;
try {
cout << "Connecting to database server..." << endl;
- connect_to_db(argc, argv, con, "");
+ if (!connect_to_db(argc, argv, con, "")) {
+ return 1;
+ }
}
catch (exception& er) {
cerr << "Connection failed: " << er.what() << endl;
@@ -68,8 +70,9 @@
if (con.select_db(kpcSampleDatabase)) {
// Toss old table, if it exists. If it doesn't, we
don't
// really care, as it'll get created next.
- cout << "Dropping existing stock table..." << endl;
+ cout << "Dropping existing sample data tables..." <<
endl;
query.execute("drop table stock");
+ query.execute("drop table images");
}
else {
// Database doesn't exist yet, so create and select it.
@@ -85,17 +88,17 @@
}
// Create sample data table within sample database.
- cout << "Creating new stock table..." << endl;
try {
- // Send the query to create the table and execute it.
+ // Send the query to create the stock table and execute it.
+ cout << "Creating stock table..." << endl;
mysqlpp::Query query = con.query();
query <<
- "CREATE TABLE stock " <<
- "(item CHAR(20) NOT NULL, " <<
- " num BIGINT, " <<
- " weight DOUBLE, " <<
- " price DOUBLE, " <<
- " sdate DATE) " <<
+ "CREATE TABLE stock (" <<
+ " item CHAR(20) NOT NULL, " <<
+ " num BIGINT, " <<
+ " weight DOUBLE, " <<
+ " price DOUBLE, " <<
+ " sdate DATE) " <<
"ENGINE = InnoDB " <<
"CHARACTER SET utf8 COLLATE utf8_general_ci";
query.execute();
@@ -120,6 +123,19 @@
query.execute("Hot Mustard", 75, .95, .97, "1998-05-25");
query.execute("Hotdog Buns", 65, 1.1, 1.1, "1998-04-23");
+ // Now create empty images table, for testing BLOB and auto-
+ // increment column features.
+ cout << "Creating empty images table..." << endl;
+ query.reset();
+ query <<
+ "CREATE TABLE images (" <<
+ " id INT UNSIGNED NOT NULL AUTO_INCREMENT, " <<
+ " data BLOB, " <<
+ " PRIMARY KEY (id)" <<
+ ")";
+ query.execute();
+
+ // Report success
cout << (new_db ? "Created" : "Reinitialized") <<
" sample database successfully." << endl;
}
Modified: trunk/examples/util.cpp
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/util.cpp?rev=1447&r1=1446&r2=1447&view=diff
==============================================================================
--- trunk/examples/util.cpp (original)
+++ trunk/examples/util.cpp Sat Mar 17 07:02:54 2007
@@ -218,6 +218,32 @@
}
+//// print_usage ///////////////////////////////////////////////////////
+// Show the program's usage message
+
+void
+print_usage(const char* program_name, const char* extra_parms)
+{
+ cout << "usage: " << program_name <<
+ " [host [user [password [port]]]] " << extra_parms <<
endl;
+ cout << endl;
+ cout << " If no arguments are given, connects to database "
+ "server on localhost" << endl;
+ cout << " using your user name and no password. You may give "
+ "any number of" << endl;
+ cout << " these arguments, but they must be in the order "
+ "listed, and you" << endl;
+ cout << " cannot skip preceding arguments." << endl;
+ if (strlen(extra_parms) > 0) {
+ cout << endl;
+ cout << " The extra parameter " << extra_parms <<
+ " is required, regardless of which" << endl;
+ cout << " other arguments you pass." << endl;
+ }
+ cout << endl;
+}
+
+
//// connect_to_db /////////////////////////////////////////////////////
// Establishes a connection to a MySQL database server, optionally
// attaching to database kdb. This is basically a command-line parser
@@ -238,17 +264,7 @@
}
if ((argc > 1) && (argv[1][0] == '-')) {
- cout << "usage: " << argv[0] <<
- " [host] [user] [password] [port]" << endl;
- cout << endl << "\tConnects to database ";
- if (strlen(kdb) > 0) {
- cout << '"' << kdb << '"';
- }
- else {
- cout << "server";
- }
- cout << " on localhost using your user" << endl;
- cout << "\tname and no password by default." << endl << endl;
+ print_usage(argv[0]);
return false;
}
Modified: trunk/examples/util.h
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/util.h?rev=1447&r1=1446&r2=1447&view=diff
==============================================================================
--- trunk/examples/util.h (original)
+++ trunk/examples/util.h Sat Mar 17 07:02:54 2007
@@ -40,6 +40,8 @@
void print_stock_rows(mysqlpp::Result& res);
void print_stock_table(mysqlpp::Query& query);
void get_stock_table(mysqlpp::Query& query, mysqlpp::Result& res);
+void print_usage(const char* program_name,
+ const char* extra_parms = "");
bool connect_to_db(int argc, char *argv[], mysqlpp::Connection& con,
const char* kdb = 0);
char* utf8trans(const char* utf8_str, char* ansi_str, int ansi_len);
Modified: trunk/mysql++.bkl
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/mysql%2B%2B.bkl?rev=1447&r1=1446&r2=1447&view=diff
==============================================================================
--- trunk/mysql++.bkl (original)
+++ trunk/mysql++.bkl Sat Mar 17 07:02:54 2007
@@ -232,6 +232,9 @@
<exe id="fieldinf1" template="util-example,common-example">
<sources>examples/fieldinf1.cpp</sources>
</exe>
+ <exe id="load_file" template="util-example,common-example">
+ <sources>examples/load_file.cpp</sources>
+ </exe>
<exe id="xaction" template="util-example,common-example">
<sources>examples/xaction.cpp</sources>
</exe>
@@ -239,9 +242,6 @@
<!-- The few examples that don't use the util module -->
<exe id="cgi_image" template="common-example">
<sources>examples/cgi_image.cpp</sources>
- </exe>
- <exe id="load_file" template="common-example">
- <sources>examples/load_file.cpp</sources>
</exe>
<exe id="updel" template="common-example">
<sources>examples/updel.cpp</sources>
_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits