[Sending this again, in case my previous post landed in spam folders. ]
Hi.
In extending the Dbo build in types to custom types, I've found
it convenient to add a building block void * blob type, to
make it straightforward to implement fixed sized elements,
rather than using the std::vector<unsigned char> which
I found a bit clumsy for this purpose.
Attached is a patch for the added void * type. (Note that
the size parameter is needed set the blob size correctly in
statement->bind().)
Graeme Gill.
*** orig_319/src/Wt/Dbo/SqlConnection Sun Oct 17 01:54:31 2010
--- 319/src/Wt/Dbo/SqlConnection Mon Nov 28 18:19:33 2011
***************
*** 150,155 ****
--- 150,156 ----
/*! \brief Returns the blob type.
*
* \sa SqlStatement::bind(int, const std::vector<unsigned char>&)
+ * \sa SqlStatement::bind(int, const void *)
*/
virtual const char *blobType() const = 0;
//@}
*** orig_319/src/Wt/Dbo/SqlStatement Tue Oct 19 20:21:24 2010
--- 319/src/Wt/Dbo/SqlStatement Mon Nov 28 18:17:10 2011
***************
*** 95,100 ****
--- 95,104 ----
*/
virtual void bind(int column, const std::vector<unsigned char>& value) = 0;
+ /*! \brief Binds a value to a column.
+ */
+ virtual void bind(int column, const void *value, int size) = 0;
+
/*! \brief Binds \c null to a column.
*/
virtual void bindNull(int column) = 0;
***************
*** 177,182 ****
--- 181,192 ----
virtual bool getResult(int column, std::vector<unsigned char> *value,
int size) = 0;
+ /*! \brief Fetches a result value.
+ *
+ * Returns \c true when the value was not \c null.
+ */
+ virtual bool getResult(int column, void *value, int size) = 0;
+
/*! \brief Returns the prepared SQL string.
*/
virtual std::string sql() const = 0;
*** orig_319/src/Wt/Dbo/SqlTraits Fri Jan 28 21:58:27 2011
--- 319/src/Wt/Dbo/SqlTraits Mon Nov 28 18:20:01 2011
***************
*** 37,42 ****
--- 37,43 ----
* - enum types
* - <tt>bool</tt>
* - <tt>std::vector<unsigned char></tt> (binary data)
+ * - <tt>void *</tt> (binary data)
* - <tt>boost::optional<T></tt>: to make the type optional
* (allowing an SQL <tt>null</tt> value)
*
*** orig_319/src/Wt/Dbo/StdSqlTraits Thu Jan 13 19:45:18 2011
--- 319/src/Wt/Dbo/StdSqlTraits Mon Nov 28 18:17:23 2011
***************
*** 128,133 ****
--- 128,143 ----
int column, int size);
};
+ template<>
+ struct WTDBO_API sql_value_traits<void *, void>
+ {
+ static const bool specialized = true;
+
+ static const char *type(SqlConnection *conn, int size);
+ static void bind(const void *v, SqlStatement *statement, int column, int
size);
+ static bool read(void *v, SqlStatement *statement, int column, int size);
+ };
+
template<typename T>
struct sql_value_traits<boost::optional<T>, void>
{
*** orig_319/src/Wt/Dbo/StdSqlTraits.C Thu Jan 13 19:45:18 2011
--- 319/src/Wt/Dbo/StdSqlTraits.C Mon Nov 28 18:17:32 2011
***************
*** 241,246 ****
--- 241,266 ----
return statement->getResult(column, &v, size);
}
+ /*
+ * void *
+ */
+
+ const char *sql_value_traits<void *>
+ ::type(SqlConnection *conn, int size)
+ {
+ return conn->blobType();
+ }
+
+ void sql_value_traits<void *>::bind(const void *v, SqlStatement *statement,
int column, int size)
+ {
+ statement->bind(column, v, size);
+ }
+
+ bool sql_value_traits<void *>::read(void *v, SqlStatement *statement, int
column, int size)
+ {
+ return statement->getResult(column, v, size);
+ }
+
}
}
*** orig_319/src/Wt/Dbo/backend/Sqlite3.C Tue Mar 22 02:09:57 2011
--- 319/src/Wt/Dbo/backend/Sqlite3.C Mon Nov 28 18:23:53 2011
***************
*** 175,180 ****
--- 175,195 ----
handleErr(err);
}
+ virtual void bind(int column, const void *value, int size)
+ {
+ DEBUG(std::cerr << this << " bind " << column << " (blob, size=" <<
+ size << ")" << std::endl);
+
+ int err;
+
+ if (size == 0)
+ err = sqlite3_bind_blob(st_, column + 1, "", 0, SQLITE_TRANSIENT);
+ else
+ err = sqlite3_bind_blob(st_, column + 1, value, size, SQLITE_STATIC);
+
+ handleErr(err);
+ }
+
virtual void bindNull(int column)
{
DEBUG(std::cerr << this << " bind " << column << " null" << std::endl);
***************
*** 417,422 ****
--- 432,456 ----
return true;
}
+ virtual bool getResult(int column, void *value, int size)
+ {
+ if (sqlite3_column_type(st_, column) == SQLITE_NULL)
+ return false;
+
+ int s = sqlite3_column_bytes(st_, column);
+ unsigned char *v = (unsigned char *)sqlite3_column_blob(st_, column);
+
+ if (s < size) // Or should we error ?
+ size = s;
+ memmove(value, v, s);
+
+ DEBUG(std::cerr << this
+ << " result blob " << column << " (blob, size = " << s << ")"
+ << std::endl);
+
+ return true;
+ }
+
virtual std::string sql() const {
return sql_;
*** orig_319/src/Wt/Dbo/backend/Postgres.C Fri Apr 1 21:35:50 2011
--- 319/src/Wt/Dbo/backend/Postgres.C Mon Nov 28 18:23:39 2011
***************
*** 158,163 ****
--- 158,182 ----
// statement if necessary because the type changes
}
+ virtual void bind(int column, const void *value, int size)
+ {
+ DEBUG(std::cerr << this << " bind " << column << " (blob, size=" <<
+ size << ")" << std::endl);
+
+ for (int i = (int)params_.size(); i <= column; ++i)
+ params_.push_back(Param());
+
+ Param& p = params_[column];
+ p.value.resize(size);
+ if (size > 0)
+ memcpy(const_cast<char *>(p.value.data()), value, size);
+ p.isbinary = true;
+ p.isnull = false;
+
+ // FIXME if first null was bound, check here and invalidate the prepared
+ // statement if necessary because the type changes
+ }
+
virtual void bindNull(int column)
{
DEBUG(std::cerr << this << " bind " << column << " null" << std::endl);
***************
*** 420,425 ****
--- 439,466 ----
return true;
}
+ virtual bool getResult(int column, *value, int size)
+ {
+ if (PQgetisnull(result_, row_, column))
+ return false;
+
+ const char *escaped = PQgetvalue(result_, row_, column);
+
+ std::size_t vlength;
+ unsigned char *v = PQunescapeBytea((unsigned char *)escaped, &vlength);
+
+ if (vlength < size) // Or should this error ?
+ size = vlength;
+ memcpy(value, v, size);
+ PQfreemem(v);
+
+ DEBUG(std::cerr << this
+ << " result blob " << column << " (blob, size = " << vlength << ")"
+ << std::endl);
+
+ return true;
+ }
+
virtual std::string sql() const {
return sql_;
}
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure
contains a definitive record of customers, application performance,
security threats, fraudulent activity, and more. Splunk takes this
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
witty-interest mailing list
witty-interest@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/witty-interest