SQLSerialize.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #include "SQLSerialize.h"
00039 #include "SQLImplementation.h"
00040 
00041 #include "debug/DebugUtils.h"
00042 #include "debug/Log.h"
00043 #include "util/StringUtils.h"
00044 
00045 namespace oasys {
00046 
00047 /******************************************************************************
00048  *
00049  * SQLQuery
00050  *
00051  *****************************************************************************/
00052 
00056 SQLQuery::SQLQuery(action_t type, const char* table_name,
00057                    SQLImplementation* impl, const char* initial_query)
00058     
00059     : SerializeAction(type, Serialize::CONTEXT_LOCAL),
00060       table_name_(table_name),
00061       sql_impl_(impl),
00062       query_(256, initial_query)
00063 {
00064 }
00065 
00066 /******************************************************************************
00067  *
00068  * SQLInsert
00069  *
00070  *****************************************************************************/
00071 
00075 SQLInsert::SQLInsert(const char* table_name, SQLImplementation* impl)
00076     : SQLQuery(Serialize::MARSHAL, table_name, impl)
00077 {
00078 }
00079 
00080 
00081 // Virtual functions inherited from SerializeAction
00082 
00086 void 
00087 SQLInsert::begin_action() 
00088 {
00089     query_.appendf("INSERT INTO %s  VALUES(",table_name_);
00090 }
00091 
00096 void 
00097 SQLInsert::end_action() 
00098 {
00099     if (query_.data()[query_.length() - 1] == ',') {
00100         query_.data()[query_.length() - 1] = ')';
00101     }
00102 }
00103 
00104 
00105 void 
00106 SQLInsert::process(const char* name, u_int32_t* i)
00107 {
00108     (void)name;
00109     query_.appendf("%u,", *i);
00110 }
00111 
00112 void 
00113 SQLInsert::process(const char* name, u_int16_t* i)
00114 {
00115     (void)name;
00116     query_.appendf("%u,", *i);
00117 }
00118 
00119 void 
00120 SQLInsert::process(const char* name, u_int8_t* i)
00121 {
00122     (void)name;
00123     query_.appendf("%u,", *i);
00124 }
00125 
00126 void 
00127 SQLInsert::process(const char* name, int32_t* i)
00128 {
00129     (void)name;
00130 #ifdef __CYGWIN__
00131     query_.appendf("%ld,", *i);
00132 #else
00133     query_.appendf("%d,", *i);
00134 #endif
00135 }
00136 
00137 void 
00138 SQLInsert::process(const char* name, int16_t* i)
00139 {
00140     (void)name;
00141     query_.appendf("%d,", *i);
00142 }
00143 
00144 void 
00145 SQLInsert::process(const char* name, int8_t* i)
00146 {
00147     (void)name;
00148     query_.appendf("%d,", *i);
00149 }
00150 
00151 void 
00152 SQLInsert::process(const char* name, bool* b)
00153 {
00154     (void)name;
00155     if (*b) {
00156         query_.append("'TRUE',");
00157     } else {
00158         query_.append("'FALSE',");
00159     }
00160 }
00161 
00162 
00163 void 
00164 SQLInsert::process(const char* name, std::string* s) 
00165 {
00166     (void)name;
00167     query_.appendf("'%s',", sql_impl_->escape_string(s->c_str()));
00168 }
00169 
00170 void 
00171 SQLInsert::process(const char* name, u_char* bp, size_t len)
00172 {
00173     (void)name;
00174     query_.appendf("'%s',", sql_impl_->escape_binary(bp, len));
00175 }
00176 
00177 void 
00178 SQLInsert::process(const char* name, u_char** bp, size_t* lenp, int flags)
00179 {
00180     (void)name;
00181     (void)bp;
00182     (void)lenp;
00183     (void)flags;
00184     NOTIMPLEMENTED;
00185 }
00186 
00187 /******************************************************************************
00188  *
00189  * SQLUpdate
00190  *
00191  *****************************************************************************/
00192 
00196 SQLUpdate::SQLUpdate(const char* table_name, SQLImplementation* impl)
00197     : SQLQuery(Serialize::MARSHAL, table_name, impl)
00198 {
00199 }
00200 
00201 
00202 // Virtual functions inherited from SerializeAction
00203 void 
00204 SQLUpdate::begin_action() 
00205 {
00206     query_.appendf("UPDATE %s SET ",table_name_);
00207 }
00208 
00209 void 
00210 SQLUpdate::end_action() 
00211 {
00212     if (query_.data()[query_.length() - 2] == ',') {
00213         query_.data()[query_.length() - 2] =  ' ';
00214     }
00215 }
00216 
00217 void 
00218 SQLUpdate::process(const char* name, u_int32_t* i)
00219 {
00220     (void)name;
00221     query_.appendf("%s = %u, ", name, *i);
00222 }
00223 
00224 void 
00225 SQLUpdate::process(const char* name, u_int16_t* i)
00226 {
00227     (void)name;
00228     query_.appendf("%s = %u, ", name, *i);
00229 }
00230 
00231 void 
00232 SQLUpdate::process(const char* name, u_int8_t* i)
00233 {
00234     (void)name;
00235     query_.appendf("%s = %u, ", name, *i);
00236 }
00237 
00238 void 
00239 SQLUpdate::process(const char* name, int32_t* i)
00240 {
00241     (void)name;
00242 #ifdef __CYGWIN__
00243     query_.appendf("%s = %ld, ", name, *i);
00244 #else
00245     query_.appendf("%s = %d, ", name, *i);
00246 #endif
00247 }
00248 
00249 void 
00250 SQLUpdate::process(const char* name, int16_t* i)
00251 {
00252     (void)name;
00253     query_.appendf("%s = %d, ", name, *i);
00254 }
00255 
00256 void 
00257 SQLUpdate::process(const char* name, int8_t* i)
00258 {
00259     (void)name;
00260     query_.appendf("%s = %d, ", name, *i);
00261 }
00262 
00263 void 
00264 SQLUpdate::process(const char* name, bool* b)
00265 {
00266     (void)name;
00267     if (*b) {
00268         query_.appendf("%s = 'TRUE', ", name);
00269     } else {
00270         query_.appendf("%s = 'FALSE', ", name);
00271     }
00272 }
00273 
00274 
00275 void 
00276 SQLUpdate::process(const char* name, std::string* s) 
00277 {
00278     (void)name;
00279     query_.appendf("%s = '%s', ", name, sql_impl_->escape_string(s->c_str()));
00280 }
00281 
00282 void 
00283 SQLUpdate::process(const char* name, u_char* bp, size_t len)
00284 {
00285     (void)name;
00286     query_.appendf("%s = '%s', ", name, sql_impl_->escape_binary(bp, len));
00287 }
00288 
00289 void 
00290 SQLUpdate::process(const char* name, u_char** bp, size_t* lenp, int flags)
00291 {
00292     (void)name;
00293     (void)bp;
00294     (void)lenp;
00295     (void)flags;
00296     NOTIMPLEMENTED;
00297 }
00298 
00299 /******************************************************************************
00300  *
00301  * SQLTableFormat
00302  *
00303  *****************************************************************************/
00304 
00309 SQLTableFormat::SQLTableFormat(const char* table_name,
00310                                SQLImplementation* impl)
00311     : SQLQuery(Serialize::INFO, table_name, impl)
00312 {
00313 }
00314 
00315 
00316 // Virtual functions inherited from SerializeAction
00317 
00318 void 
00319 SQLTableFormat::begin_action() 
00320 {
00321     query_.appendf("CREATE TABLE  %s  (",table_name_);
00322 }
00323 
00324 void 
00325 SQLTableFormat::end_action() 
00326 {
00327     if (query_.data()[query_.length() - 1] == ',') {
00328         query_.data()[query_.length() - 1] =  ')';
00329     }
00330 }
00331 
00332 
00333 void
00334 SQLTableFormat::process(const char* name,  SerializableObject* object) 
00335 {
00336     int old_len = column_prefix_.length();
00337 
00338     column_prefix_.appendf("%s__", name);
00339     object->serialize(this);
00340     column_prefix_.trim(column_prefix_.length() - old_len);
00341 }
00342 
00343 void 
00344 SQLTableFormat::append(const char* name, const char* type)
00345 {
00346     query_.appendf("%.*s%s %s,",
00347                    (int)column_prefix_.length(), column_prefix_.data(),
00348                    name, type);
00349 }
00350 
00351 // Virtual functions inherited from SerializeAction
00352 void 
00353 SQLTableFormat::process(const char* name, u_int32_t* i)
00354 {
00355     (void)i;
00356     append(name, "BIGINT");
00357 }
00358 
00359 void 
00360 SQLTableFormat::process(const char* name, u_int16_t* i)
00361 {
00362     (void)i;
00363     append(name, "INTEGER");
00364 }
00365 
00366 void
00367 SQLTableFormat::process(const char* name, u_int8_t* i) {
00368 
00369     (void)i;
00370     append(name, "SMALLINT");
00371 }
00372  
00373 
00374 // Mysql and Postgres do not have common implementation of bool
00375 // XXX/demmer fix this
00376 void 
00377 SQLTableFormat::process(const char* name, bool* b)
00378 {
00379     (void)b;
00380 //    append(name, "BOOLEAN");
00381     append(name, "TEXT");
00382 }
00383 
00384 void 
00385 SQLTableFormat::process(const char* name, std::string* s) 
00386 {
00387     (void)s;
00388     append(name, "TEXT");
00389 }
00390 
00391 void 
00392 SQLTableFormat::process(const char* name, u_char* bp, size_t len)
00393 {
00394     (void)bp;
00395     (void)len;
00396     append(name,sql_impl_->binary_datatype());
00397 }
00398     
00399 void 
00400 SQLTableFormat::process(const char* name, u_char** bp, size_t* lenp, int flags)
00401 {
00402     (void)bp;
00403     (void)lenp;
00404     (void)flags;
00405 
00406     if (flags & Serialize::NULL_TERMINATED) {
00407         NOTIMPLEMENTED;
00408     }
00409 
00410     append(name,sql_impl_->binary_datatype());
00411 }
00412 
00413 /******************************************************************************
00414  *
00415  * SQLExtract
00416  *
00417  *****************************************************************************/
00418 
00423 SQLExtract::SQLExtract(SQLImplementation* impl)
00424     : SerializeAction(Serialize::UNMARSHAL, 
00425                       Serialize::CONTEXT_LOCAL)
00426 {
00427     field_ = 0;
00428     sql_impl_ = impl;
00429 }
00430 
00431 const char* 
00432 SQLExtract::next_field()
00433 {
00434     return sql_impl_->get_value(0, field_++);
00435 }
00436 
00437 void
00438 SQLExtract::process(const char* name, u_int32_t* i)
00439 {
00440     (void)name;
00441     const char* buf = next_field();
00442     if (buf == NULL) return;
00443     
00444     *i = atoi(buf) ; 
00445 
00446     if (log_) logf(log_, LOG_DEBUG, "<=int32(%d)", *i);
00447 }
00448 
00449 void 
00450 SQLExtract::process(const char* name, u_int16_t* i)
00451 {
00452     (void)name;
00453     const char* buf = next_field();
00454     if (buf == NULL) return;
00455 
00456     *i = atoi(buf) ; 
00457     
00458     if (log_) logf(log_, LOG_DEBUG, "<=int16(%d)", *i);
00459 }
00460 
00461 void 
00462 SQLExtract::process(const char* name, u_int8_t* i)
00463 {
00464     (void)name;
00465     const char* buf = next_field();
00466     if (buf == NULL) return;
00467     
00468     *i = buf[0];
00469     
00470     if (log_) logf(log_, LOG_DEBUG, "<=int8(%d)", *i);
00471 }
00472 
00473 void 
00474 SQLExtract::process(const char* name, bool* b)
00475 {
00476     (void)name;
00477     const char* buf = next_field();
00478 
00479     if (buf == NULL) return;
00480 
00481     switch(buf[0]) {
00482     case 'T':
00483     case 't':
00484     case '1':
00485     case '\1':
00486         *b = true;
00487         break;
00488     case 'F':
00489     case 'f':
00490     case '0':
00491     case '\0':
00492         *b = false;
00493         break;
00494     default:
00495         logf("/sql", LOG_ERR, "unexpected value '%s' for boolean column", buf);
00496         signal_error();
00497         return;
00498     }
00499     
00500     if (log_) logf(log_, LOG_DEBUG, "<=bool(%c)", *b ? 'T' : 'F');
00501 }
00502 
00503 void 
00504 SQLExtract::process(const char* name, std::string* s)
00505 {
00506     (void)name;
00507     const char* buf = next_field();
00508     if (buf == NULL) return;
00509     
00510     s->assign(buf);
00511     
00512     size_t len = s->length();
00513     
00514     if (log_) logf(log_, LOG_DEBUG, "<=string(%zu: '%.*s')",
00515                    len, (int)(len < 32 ? len : 32), s->data());
00516 }
00517 
00518 void 
00519 SQLExtract::process(const char* name, u_char* bp, size_t len)
00520 {
00521     (void)name;
00522     const char* buf = next_field();
00523     if (buf == NULL) return;
00524  
00525     const u_char* v = sql_impl_->unescape_binary((const u_char*)buf);
00526 
00527     memcpy(bp, v, len);
00528     if (log_) {
00529         std::string s;
00530         hex2str(&s, bp, len < 16 ? len : 16);
00531         logf(log_, LOG_DEBUG, "<=bufc(%zu: '%.*s')",
00532              len, (int)s.length(), s.data());
00533     }
00534 
00535 }
00536 
00537 
00538 void 
00539 SQLExtract::process(const char* name, u_char** bp, size_t* lenp, int flags)
00540 {
00541     (void)name;
00542     (void)bp;
00543     (void)lenp;
00544     (void)flags;
00545     NOTIMPLEMENTED;
00546 }
00547 
00548 } // namespace oasys

Generated on Fri Dec 22 14:48:00 2006 for DTN Reference Implementation by  doxygen 1.5.1