TypeHandler - parameter count mismatch

Please post support and help requests here.
roggan87
Posts: 14
Joined: 05 May 2011, 12:42

TypeHandler - parameter count mismatch

Postby roggan87 » 19 Jul 2013, 21:44

Hi!

First off, thanks for a fantastic library, it fits our needs perfectly!

I have an SQLite database with a table. To that table I have an object with a TypeHandler. The thing is that I would like to return one more column on select than on insert. This is since I want to put the results of the select statement into a map where the rowid is the identifier. However it would make no sense to insert a rowid, since it should be given automatically.

Any ideas on how I could avoid the parameter count mismatch  error?

(sorry for not providing code, I haven't got it here, but please ask if I should clarify something)

Thanks,
Robert

roggan87
Posts: 14
Joined: 05 May 2011, 12:42

Re: TypeHandler - parameter count mismatch

Postby roggan87 » 31 Jul 2013, 01:07

Okay, some code example:

Code: Select all

   // Setup
   session <<"CREATE TABLE IF NOT EXISTS rows "
         <<"(col1 TEXT, col2 TEXT)", now;

   // Insert
   Row row = Row("first", "second");
   session <<"INSERT INTO rows VALUES(:col1, :col2)", use(row), now;

   // Select
   vector<Row> rows;
   session <<"SELECT rowid, col1, col2 FROM rows;", into(rows), now;


Note how I don't want to insert any rowid, since it is automatically increased. I do want to extract it on select though, since the rowid will be used as id for the object. It seems really hard to achieve this, to extract more columns than are inserted. When making the TypeHandler template, I have to specify exactly how many fields to be handled, like this:

Code: Select all

template <>
class TypeHandler<Row>
{
public:
   static size_t size()
   {
      return 3;
   }
   ...


That is however hard to say. Is there any way to workaround this issue?

petecode
Posts: 1
Joined: 25 Feb 2017, 05:45

Re: TypeHandler - parameter count mismatch

Postby petecode » 25 Feb 2017, 06:05

I ran into the same issue and created a *hack* workaround. I simply doubled up one of the fields in the INSERT statement (and doubled the set in bind) so my size was always the same. Using your example it looked like:

Code: Select all

// Insert
   Row row = Row("first", "second");
   session <<"INSERT INTO rows (first, first, second) VALUES(?,?,?)", use(row), now;


and bind in the the TypeHandler would be

Code: Select all

  static void bind(std::size_t pos, const Row& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) {
             TypeHandler<std::string>::bind(pos++, obj.getFirst(), pBinder, dir); //pos++; by itself will work here too.
             TypeHandler<std::string>::bind(pos++, obj.geFirst(), pBinder, dir);
             TypeHandler<std::string>::bind(pos++, obj.getSecond(), pBinder, dir);



The fields would not be duplicated on the select:

Code: Select all

  // Select
   vector<Row> rows;
   session <<"SELECT rowid, col1, col2 FROM rows;", into(rows), now


and the extract method on the TypeDef would be:

Code: Select all

  static void extract(std::size_t pos, Row& obj, const Row& defVal, AbstractExtractor::Ptr pExt){
     uint64_t rowId;
     std::string first;
     std::string second;
    
       TypeHandler<uint64_t>::extract(pos++, rowId, defVal.getRowId(), pExt);
       TypeHandler<std::string>::extract(pos++, first, defVal.getFirst(), pExt);
       TypeHandler<std::string>::extract(pos++, second, defVal.getSecond(), pExt);
      
       obj.setRowId(rowId);
       obj.setFirst(first);
       obj.setSecond(second);
  }
 


Again, I recognize this is a hack and I'd love to hear what the official solution to using TypeHandlers with generated id's is.


Return to “Support”

Who is online

Users browsing this forum: No registered users and 5 guests

cron