Browse Source

API Refactoring - changed execute() to be query(), use when results expected

Erik Winn 7 years ago
parent
commit
60cb0f3a99

+ 1
- 1
Doxyfile View File

@@ -1303,7 +1303,7 @@ RTF_EXTENSIONS_FILE    =
1303 1303
 # If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
1304 1304
 # generate man pages
1305 1305
 
1306
-GENERATE_MAN           = YES
1306
+GENERATE_MAN           = NO
1307 1307
 
1308 1308
 # The MAN_OUTPUT tag is used to specify where the man pages will be put. 
1309 1309
 # If a relative path is entered the value of OUTPUT_DIRECTORY will be 

+ 13
- 13
README View File

@@ -7,7 +7,7 @@ it under the terms of the GNU General Public License as published by
7 7
 the Free Software Foundation, either version 3 of the License, or
8 8
 (at your option) any later version.
9 9
 
10
-2011-10-28 - Version 0.2 UNSTABLE
10
+2011-11-18 - Version 0.2 UNSTABLE
11 11
 
12 12
 WORM is a Data Abstraction Layer for access to database servers and an
13 13
 Object Relational Mapping system.  It consists of libraries providing a
@@ -26,17 +26,17 @@ The output is configurable using the WORM template system which uses
26 26
 google's ctemplate for output templating.
27 27
 
28 28
 Additionally the libraries provide a general API for basic database access
29
-including query execution with structured result sets and runtime metadata 
29
+including query execution with structured result sets and runtime metadata
30 30
 including column information such as name, data type, defaults, extras, etc.
31 31
 
32 32
 NOTE: This API is not fully stable! I expect there to be some changes and
33
-do not yet recommend building off the API for anything serious.  wormgen 
34
-is functional (if simple) and changes there should not cause problems but 
35
-the libraries are under heavy development.  There may be modifications 
33
+do not yet recommend building off the API for anything serious.  wormgen
34
+is functional (if simple) and changes there should not cause problems but
35
+the libraries are under heavy development.  There may be modifications
36 36
 and these should be expected until this message is removed.
37 37
 You have been warned :).
38 38
 
39
-NOTE: THIS IS UNTESTED ON WINDOWS or MAC AND NOT LIKELY TO WORK CURRENTLY.. 
39
+NOTE: THIS IS UNTESTED ON WINDOWS or MAC AND NOT LIKELY TO WORK CURRENTLY..
40 40
 linux or Unices should be ok.
41 41
 
42 42
 Requirements:
@@ -74,7 +74,7 @@ You must be root to install.
74 74
  make install  (OR) sudo make install
75 75
  ldconfig
76 76
 
77
- * This will install the libraries to /usr/local/lib/libworm.* and the 
77
+ * This will install the libraries to /usr/local/lib/libworm.* and the
78 78
  * binary to /usr/local/bin/wormgen.  Code generation templates will
79 79
  * be installed to /usr/local/share/worm/
80 80
 
@@ -84,7 +84,7 @@ it was built with the shared libraries:
84 84
 
85 85
 export LD_LIBRARY_PATH=./build/src
86 86
 ./build/src/wormgen
87
- 
87
+
88 88
  Uninstall:
89 89
   rm /usr/local/bin/wormgen
90 90
   rm /usr/local/lib/libworm*
@@ -96,7 +96,7 @@ Alternately you can do:
96 96
 wormgen Usage:
97 97
 wormgen -h gives help on usage.
98 98
 
99
-The database argument is the only required argument - you must have 
99
+The database argument is the only required argument - you must have
100 100
 a database already set up and access to it.  By default it assumes the username
101 101
 is root with no password - for an SQlite3 database pass the filename as the
102 102
 argument for -d database; eg.:
@@ -115,7 +115,7 @@ Other commandline arguments include:
115 115
 
116 116
 Output:
117 117
 The output can be configured by editing or creating new template files
118
-in the template directory - any files in this directory are assumed to be 
118
+in the template directory - any files in this directory are assumed to be
119 119
 templates to use. These are the supported template types:
120 120
 
121 121
 base class header - generates FooBase.h:
@@ -153,9 +153,9 @@ ctemplate syntax is available at the ctemplate website. The supported tags are
153 153
 quite simple and self-explanatory - see the default template for more.
154 154
 
155 155
 Library Usage and Documentation:
156
+
156 157
 There are some small example programs under examples/ - I recommend
157
-starting with these.  Also, the code is heavily commented - if you have
158
-doxygen installed the Doxyfile will generate HTML documentation
159
-under doc/
158
+starting with these.  Also, the code is heavily commented - and there are copious
159
+amounts of HTML formatted documentation under doc/html..
160 160
 
161 161
 Enjoy!

+ 1
- 1
examples/test_wmysqlresultset.cpp View File

@@ -42,7 +42,7 @@ int main()
42 42
         }
43 43
         
44 44
         std::string sql = "select * from " + *it + " limit 2;";
45
-        if(!db.execute(sql))
45
+        if(!db.query(sql))
46 46
         {
47 47
             std::cout << "Query Failed: " << db.error().text() << std::endl;
48 48
             it++;

+ 1
- 1
examples/test_wsqlresultset.cpp View File

@@ -17,7 +17,7 @@ int main()
17 17
     while (it != tables.end()) 
18 18
     {
19 19
         std::string sql = "select * from " + *it + " ;";
20
-        if(!db.execute(sql))
20
+        if(!db.query(sql))
21 21
         {
22 22
             std::cerr << "Query Failed: " << db.error().text() << std::endl;
23 23
             it++;

+ 15
- 12
src/sql/drivers/wmysqldriver.cpp View File

@@ -154,12 +154,13 @@ bool WMysqlDriver::open()
154 154
     
155 155
     \returns bool on success
156 156
 */
157
-bool WMysqlDriver::execute(std::string sqlstring )
157
+bool WMysqlDriver::query(std::string sqlstring )
158 158
 {
159 159
     if(!isOpen())
160 160
         return false;
161 161
     
162
-// \todo RESOLVE - this also escapes LIKE quotes .. need a way to handle this.
162
+/// \todo RESOLVE - this also escapes LIKE quotes .. need a way to handle this, ie.
163
+///a general escape/sanitizer method somewhere ..
163 164
 // for now it is disabled
164 165
 // FIXME       std::string sql = local_escape_string(sqlstring);
165 166
         
@@ -187,19 +188,19 @@ bool WMysqlDriver::execute(std::string sqlstring )
187 188
  The parameter \a iscached may be set to true to indicate a non-cached result
188 189
  set that will be fetched row by row - the default is true and results are cached.
189 190
  
190
- \note Only use this \em after an execute() query! Do not use twice in a row as it will delete
191
+ \note Only use this \em after an query() query! Do not use twice in a row as it will delete
191 192
  the previous result and return a newly created object. Example:
192 193
 
193 194
 \code
194 195
  WSqlDatabase db;
195 196
 if (!db.open()) 
196 197
     dosomeerror();
197
-if (!db.execute(std::string("select foo from bar")))
198
+if (!db.query(std::string("select foo from bar")))
198 199
     dosomeerror();
199 200
 WSqlResult *result = db.result();
200 201
 //WSqlResult *result2 = db.result(); <- wrong 
201 202
 //...iterate over results ..._then repeat:
202
-if (!db.execute(std::string("select baz from bar")))
203
+if (!db.query(std::string("select baz from bar")))
203 204
     dosomeerror();
204 205
 WSqlResult *result = db.result();
205 206
 ..etc.
@@ -278,8 +279,8 @@ std::vector< std::string > WMysqlDriver::tableNames()
278 279
         setError("tableNames: You must set a database name first!");
279 280
         return vecToReturn;
280 281
     }
281
-    std::string query = "show tables";
282
-    execute(query);
282
+    std::string sql = "show tables";
283
+    query(sql);
283 284
     result();
284 285
     int numtables = _result->count();
285 286
     for(int i=0;i<numtables;++i)
@@ -320,7 +321,7 @@ std::vector< std::string > WMysqlDriver::tableNames()
320 321
     \warning If the table metadata has not been initialized yet this method will invalidate 
321 322
     any previous WSqlResult pointer returned - in this case nesting calls to this method inside 
322 323
     of a loop iterating over WSqlResults WILL NOT WORK. Obtain the WSqlTable \em first and 
323
-    \em then execute() a query and fetch the result set using result() or use WSqlDatabase::initMetaData()
324
+    \em then query() a query and fetch the result set using result() or use WSqlDatabase::initMetaData()
324 325
     to initialize the metadata for all tables at once.
325 326
     
326 327
     \param string the name of the table to use
@@ -341,18 +342,20 @@ WSqlTable WMysqlDriver::tableMetaData( const std::string& tableName )
341 342
     std::vector<std::string> column_names;
342 343
     std::vector<std::string>::const_iterator column_names_it;
343 344
     std::string sql("show columns in ");sql.append(tableName);
344
-    execute(sql);
345
+    query(sql);
345 346
     result();
346 347
     WSqlColumn clm;
347 348
     WSqlRecord record = _result->fetchFirst();
348 349
     while(!record.empty())
349 350
     {
350
-/*        clm.setColumnName(record.field("Field").data<std::string>());
351
+        /*! \todo change to use strings, defined? and test
352
+        clm.setColumnName(record.field("Field").data<std::string>());
351 353
         initColumnType(clm, record.field("Type").data<std::string>());
352 354
         bool nullable = ! (record.field("Null").data<std::string>().compare("NO") == 0);
353 355
         bool primarykey = (record.field("Key").data<std::string>().compare("PRI") == 0);
354 356
         clm.setDefaultValue( record.field("Default").data<std::string>());
355
-        bool isauto = (record.field("Extra").data<std::string>().find("auto_increment") != std::string::npos);*/
357
+        bool isauto = (record.field("Extra").data<std::string>().find("auto_increment") != std::string::npos);
358
+        */
356 359
         clm.setColumnName(record.field(0).data<std::string>());
357 360
         column_names.push_back(clm.columnName());
358 361
         initColumnType(clm, record.field(1).data<std::string>());
@@ -375,7 +378,7 @@ WSqlTable WMysqlDriver::tableMetaData( const std::string& tableName )
375 378
         " referenced_column_name from information_schema.key_column_usage "
376 379
         " where table_name like '" + tableName + "' and column_name like '" + *column_names_it + "'";
377 380
         
378
-        execute(sql);
381
+        query(sql);
379 382
         result();
380 383
         WSqlRecord record = _result->fetchFirst();
381 384
         while(!record.empty())

+ 2
- 1
src/sql/drivers/wmysqldriver.h View File

@@ -36,7 +36,8 @@ class WMysqlDriver : public WSqlDriver
36 36
         ~WMysqlDriver();
37 37
         bool open();
38 38
         void close();
39
-        bool execute(std::string sql );
39
+        bool query(std::string sql );
40
+//        bool execute(std::string sql );
40 41
         WSqlResult* result(bool iscached=true);
41 42
         // WSqlResult exec(const WSqlQuery &queryObject);
42 43
         std::vector<std::string> tableNames();

+ 24
- 17
src/sql/drivers/wsqlitedriver.cpp View File

@@ -36,18 +36,18 @@ namespace WSql
36 36
  * \todo This driver is unfinished. Basic functionality is there but it is not, ah, elegant.
37 37
  * Metadata is incomplete, all results are cached locally and there may be strange behavior.
38 38
  * Basically I have done enough to get sufficient metadata for the ORM generator (except
39
- * foreign keys and indices still) and execute() will perform the query and return a result
39
+ *  indices still) and query() will perform the query and return a result
40 40
  * via result(). tableNames() works and tableMetaData() works as well (with the above
41 41
  * caveats). Transactions are not supported and I seriously doubt that this is thread safe.
42 42
  * It quite is crude at the moment - your milage may vary. It _might_ work for you but
43 43
  * at this point I don't recommend it for production (10/10/2011)
44 44
  * 
45 45
  * (at a minimum) :
46
- * \li finish initializing the foreign keys and indices and fully initialize a WSqlTable.
47
- * \li clean up some of the logic and make use of execute() rather than reproducing code
46
+ * \li finish initializing the indices and fully initialize a WSqlTable.
47
+ * \li clean up some of the logic and make use of query() rather than reproducing code
48 48
  * for queries.
49
- * \li break up execute() and handle errors properly
50
- * \li see the note by execute() about creating a result set so that fields exist and have
49
+ * \li break up query() and handle errors properly
50
+ * \li see the note by query() about creating a result set so that fields exist and have
51 51
  * names even if the value is empty (ie. NULL). This is a valid return in SQL and should
52 52
  * be there!
53 53
  * \li implement transactions
@@ -271,18 +271,25 @@ void WSqliteDriver::close()
271 271
 
272 272
 //WSqlResult WSqliteDriver::exec(const WSqlQuery &queryObject){}
273 273
 
274
-//!\todo refactor this using metadata to construct a proper result set ..
275
-// sqlite doesn't return things in orderly fashion - if a field is empty
276
-// (i.e. NULL) it just doesn't include it in the results (ARG!), i _think_
277
-// and other strange random behavior is observed ..- so, we need
278
-// to construct a skeleton result set from metadata and then fill it leaving
279
-// the appropriate gaps such that the field name will _always_ be there.
280
-// We can't simply refer to tableMetaData as it may be a join or such - which
281
-// would mean parsing the query, etc..ugly The problem is that we cannot
282
-//rely on sqlite to return metadata if, for instance, the query returns no results..
283
-//Consider using sqlite3_column_metadata. 
284
-// Also, some of this might be better moved to result()
285
-bool WSqliteDriver::execute(std::string sql)
274
+/*!
275
+ * @brief Send the query \a sql to the database
276
+ * 
277
+ * \todo refactor this using metadata to construct a proper result set ..
278
+ sqlite doesn't return things in orderly fashion - if a field is empty
279
+ (i.e. NULL) it just doesn't include it in the results (ARG!), i _think_
280
+ and other strange random behavior is observed ..- so, we need
281
+ to construct a skeleton result set from metadata and then fill it leaving
282
+ the appropriate gaps such that the field name will _always_ be there.
283
+ We can't simply refer to tableMetaData as it may be a join or such - which
284
+ would mean parsing the query, etc..ugly The problem is that we cannot
285
+ rely on sqlite to return metadata if, for instance, the query returns no results..
286
+ Consider using sqlite3_column_metadata.
287
+ Also, some of this might be better moved to result()
288
+ 
289
+ * @param std::string sql containing the query string
290
+ * @retval bool
291
+ **/
292
+bool WSqliteDriver::query(std::string sql)
286 293
 {
287 294
     if ( !isOpen() ) {
288 295
         setError( std::string( "WSqliteDriver - connection not open! Call open() first. " ),

+ 1
- 1
src/sql/drivers/wsqlitedriver.h View File

@@ -38,7 +38,7 @@ class WSqliteDriver : public WSqlDriver
38 38
         ~WSqliteDriver();
39 39
         bool open();
40 40
         void close();
41
-        bool execute( std::string sql );
41
+        bool query( std::string sql );
42 42
         WSqlResult* result(bool iscached=true);
43 43
 
44 44
         std::vector<std::string> tableNames();

+ 20
- 13
src/sql/wsqldatabase.cpp View File

@@ -53,7 +53,7 @@ if ( !db.open() ) {
53 53
     return 1;
54 54
 }
55 55
 std::string sql = "select * from " + sometable + " limit 2;";
56
-if(!db.execute(sql))
56
+if(!db.query(sql))
57 57
     std::cout << "Query Failed: " << db.error().text() << std::endl;
58 58
 }else{
59 59
     WSql::WSqlResult *result = db.result();
@@ -111,7 +111,7 @@ WSqlDatabase::WSqlDatabase()
111 111
     
112 112
     This constructs a new database object initialized with the values of  \a other
113 113
      *    WARNING: This also creates a new driver! If \a other
114
-     *    is destroyed result() is invalid until the next execute() is called!    
114
+     *    is destroyed result() is invalid until the next query() is called!
115 115
 
116 116
     \param WSqlDatabase other - database to copy
117 117
 */
@@ -145,7 +145,7 @@ WSqlDatabase::~WSqlDatabase()
145 145
 /*!\brief Copies the values of \a other to this object.
146 146
  * 
147 147
     WARNING: This also creates a new driver! If \a other
148
-    is destroyed result() is invalid until the next execute()!
148
+    is destroyed result() is invalid until the next query()!
149 149
 
150 150
     \param WSqlDatabase other - database to copy
151 151
 */
@@ -410,11 +410,11 @@ std::string WSqlDatabase::hostName() const
410 410
 
411 411
 This returns a pointer to the database driver used to access the database
412 412
     connection. \em Caution! This is not meant to be used directly - use open().
413
-    close(), execute() and result() for interaction with the driver instead.  
413
+    close(), query() and result() for interaction with the driver instead.
414 414
     
415 415
     !This may be removed in future.
416 416
 
417
-    \sa open() close() execute() result()
417
+    \sa open() close() query() result()
418 418
 */
419 419
 
420 420
 WSqlDriver* WSqlDatabase::driver() const
@@ -455,7 +455,7 @@ WSqlError WSqlDatabase::error() const
455 455
   \warning If the table metadata has not been initialized yet this method will invalidate 
456 456
   any previous WSqlResult pointer returned - in this case nesting calls to this method inside 
457 457
   of a loop iterating over WSqlResults WILL NOT WORK. Obtain the WSqlTable \em first and 
458
-  \em then execute() a query and fetch the result set using result() or use initMetaData()
458
+  \em then query() a query and fetch the result set using result() or use initMetaData()
459 459
   to initialize the metadata for all tables at once.
460 460
   
461 461
 \todo Use the table type - currently does nothing.
@@ -499,7 +499,7 @@ const std::vector<std::string>& WSqlDatabase::tableNames(WSql::TableType type)
499 499
  \warning If the table metadata has not been initialized yet this method will invalidate 
500 500
  any previous WSqlResult pointer returned - in this case nesting calls to this method inside 
501 501
  of a loop iterating over WSqlResults WILL NOT WORK. Obtain the WSqlTable \em first and 
502
- \em then execute() a query and fetch the result set using result() or use initMetaData()
502
+ \em then query() a query and fetch the result set using result() or use initMetaData()
503 503
  to initialize the metadata for all tables at once.
504 504
  
505 505
  \param string the name of the table to use
@@ -591,12 +591,17 @@ bool WSqlDatabase::isValid() const
591 591
 {
592 592
     return (_isValid && 0 != _driver && _driver->isValid());
593 593
 }
594
-/*!
595
- * Executes the SQL in string \a sql - returns true on success.
594
+/*! \brief Executes the query in \a sql returning true on sucess
595
+ * 
596
+ * This method sends the query SQL in string \a sql  to the database server,
597
+ * the results of which will be available by calling result(). Use this method
598
+ * when you expect a result set, for non-result execution use execute()
599
+ * \sa result() execute()
600
+ * \retval bool true on success.
596 601
  */
597
-bool WSqlDatabase::execute(const std::string& sql)
602
+bool WSqlDatabase::query(const std::string& sql)
598 603
 {
599
-    return _driver->execute(sql);
604
+    return _driver->query(sql);
600 605
 }
601 606
 /*! \brief Returns a pointer to the result set from the most recent query
602 607
  * 
@@ -607,6 +612,8 @@ bool WSqlDatabase::execute(const std::string& sql)
607 612
  * 
608 613
  * The parameter \a iscached may be set to true to indicate a non-cached result
609 614
  * set that will be fetched row by row - the default is true and results are cached.
615
+ * Note that uncached queries may or may not be implemented in a particular
616
+ * driver - see the documentation for the specific driver to find out.
610 617
  * 
611 618
  * \note Only use this \em after an execute() query! Do not use twice in a row as it will delete
612 619
  * the previous result and return a newly created object. Example:
@@ -615,12 +622,12 @@ bool WSqlDatabase::execute(const std::string& sql)
615 622
  * WSqlDatabase db;
616 623
  * if (!db.open()) 
617 624
  *    dosomeerror();
618
- * if (!db.execute(std::string("select foo from bar")))
625
+ * if (!db.query(std::string("select foo from bar")))
619 626
  *    dosomeerror();
620 627
  * WSqlResult *result = db.result();
621 628
  * //WSqlResult *result2 = db.result(); <- wrong 
622 629
  * //...iterate over results ..._then repeat:
623
- * if (!db.execute(std::string("select baz from bar")))
630
+ * if (!db.query(std::string("select baz from bar")))
624 631
  *    dosomeerror();
625 632
  * WSqlResult *result = db.result();
626 633
  * ..etc.

+ 2
- 1
src/sql/wsqldatabase.h View File

@@ -85,7 +85,8 @@ public:
85 85
     void initMetaData();
86 86
    
87 87
     //Query interaction - wrapper around driver ..
88
-    bool execute(const std::string& sql );
88
+    bool query(const std::string& sql );
89
+//    bool execute(const std::string& sql );
89 90
     WSqlResult* result(bool iscached=true);
90 91
     bool initDriver();
91 92
     

+ 2
- 1
src/sql/wsqldriver.h View File

@@ -39,7 +39,8 @@ class WSqlDriver
39 39
 
40 40
         virtual bool open() = 0;
41 41
         virtual void close() = 0;
42
-        virtual bool execute(std::string sql) = 0;
42
+        virtual bool query(std::string sql) = 0;
43
+        //virtual bool execute(std::string sql) = 0;
43 44
         // virtual WSqlResult exec(const WSqlQuery &queryObject) = 0;
44 45
         virtual std::vector<std::string> tableNames() = 0;
45 46
         virtual WSqlTable tableMetaData( const std::string &tableName ) = 0;

BIN
src/wormgen View File