@@ -252,6 +252,18 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
252252 void bind (std::size_t pos, const std::list<std::string>& val, Direction dir);
253253 // / Binds a string list.
254254
255+ void bind (std::size_t pos, const UTF16String& val, Direction dir);
256+ // / Binds a string.
257+
258+ void bind (std::size_t pos, const std::vector<UTF16String>& val, Direction dir);
259+ // / Binds a string vector.
260+
261+ void bind (std::size_t pos, const std::deque<UTF16String>& val, Direction dir);
262+ // / Binds a string deque.
263+
264+ void bind (std::size_t pos, const std::list<UTF16String>& val, Direction dir);
265+ // / Binds a string list.
266+
255267 void bind (std::size_t pos, const BLOB & val, Direction dir);
256268 // / Binds a BLOB. In-bound only.
257269
@@ -341,18 +353,20 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
341353 // / Clears the cached storage.
342354
343355private:
344- typedef std::vector<SQLLEN *> LengthVec;
345- typedef std::vector<std::vector<SQLLEN > > LengthVecVec;
346- typedef std::vector<char *> CharPtrVec;
347- typedef std::vector<bool *> BoolPtrVec;
348- typedef std::vector<std::vector<SQL_DATE_STRUCT > > DateVec;
349- typedef std::vector<std::vector<SQL_TIME_STRUCT > > TimeVec;
350- typedef std::vector<std::vector<SQL_TIMESTAMP_STRUCT > > DateTimeVec;
351- typedef std::vector<std::vector<Poco::Any> > AnyVec;
352- typedef std::map<char *, std::string*> StringMap;
353- typedef std::map<SQL_DATE_STRUCT *, Date*> DateMap;
354- typedef std::map<SQL_TIME_STRUCT *, Time*> TimeMap;
355- typedef std::map<SQL_TIMESTAMP_STRUCT *, DateTime*> TimestampMap;
356+ typedef std::vector<SQLLEN *> LengthVec;
357+ typedef std::vector<std::vector<SQLLEN > > LengthVecVec;
358+ typedef std::vector<char *> CharPtrVec;
359+ typedef std::vector<UTF16Char*> UTF16CharPtrVec;
360+ typedef std::vector<bool *> BoolPtrVec;
361+ typedef std::vector<std::vector<SQL_DATE_STRUCT > > DateVec;
362+ typedef std::vector<std::vector<SQL_TIME_STRUCT > > TimeVec;
363+ typedef std::vector<std::vector<SQL_TIMESTAMP_STRUCT > > DateTimeVec;
364+ typedef std::vector<std::vector<Poco::Any> > AnyVec;
365+ typedef std::map<char *, std::string*> StringMap;
366+ typedef std::map<UTF16String::value_type*, UTF16String*> UTF16StringMap;
367+ typedef std::map<SQL_DATE_STRUCT *, Date*> DateMap;
368+ typedef std::map<SQL_TIME_STRUCT *, Time*> TimeMap;
369+ typedef std::map<SQL_TIMESTAMP_STRUCT *, DateTime*> TimestampMap;
356370
357371 void describeParameter (std::size_t pos);
358372 // / Sets the description field for the parameter, if needed.
@@ -581,6 +595,71 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
581595 }
582596 }
583597
598+ template <typename C>
599+ void bindImplContainerUTF16String (std::size_t pos, const C& val, Direction dir)
600+ // / Utility function to bind containers of strings.
601+ {
602+ if (isOutBound (dir) || !isInBound (dir))
603+ throw NotImplementedException (" String container parameter type can only be inbound." );
604+
605+ if (PB_IMMEDIATE != _paramBinding)
606+ throw InvalidAccessException (" Containers can only be bound immediately." );
607+
608+ if (0 == val.size ())
609+ throw InvalidArgumentException (" Empty container not allowed." );
610+
611+ setParamSetSize (val.size ());
612+
613+ SQLINTEGER size = 0 ;
614+ getColumnOrParameterSize (pos, size);
615+ poco_assert (size > 0 );
616+
617+ if (size == _maxFieldSize)
618+ {
619+ getMinValueSize (val, size);
620+ // accomodate for terminating zero
621+ if (size != _maxFieldSize) size += sizeof (UTF16Char);
622+ }
623+
624+ if (_vecLengthIndicator.size () <= pos)
625+ {
626+ _vecLengthIndicator.resize (pos + 1 );
627+ _vecLengthIndicator[pos].resize (val.size (), SQL_NTS );
628+ }
629+
630+ if (_utf16CharPtrs.size () <= pos)
631+ _utf16CharPtrs.resize (pos + 1 , 0 );
632+
633+ _utf16CharPtrs[pos] = (UTF16Char*)std::calloc (val.size () * size, sizeof (UTF16Char));
634+
635+ std::size_t strSize;
636+ std::size_t offset = 0 ;
637+ typename C::const_iterator it = val.begin ();
638+ typename C::const_iterator end = val.end ();
639+ for (; it != end; ++it)
640+ {
641+ strSize = it->size () * sizeof (UTF16Char);
642+ if (strSize > size)
643+ throw LengthExceededException (" SQLBindParameter(std::vector<UTF16String>)" );
644+ std::memcpy (_utf16CharPtrs[pos] + offset, it->data (), strSize);
645+ offset += (size / sizeof (UTF16Char));
646+ }
647+
648+ if (Utility::isError (SQLBindParameter (_rStmt,
649+ (SQLUSMALLINT )pos + 1 ,
650+ toODBCDirection (dir),
651+ SQL_C_WCHAR ,
652+ SQL_WLONGVARCHAR ,
653+ (SQLUINTEGER )size - 1 ,
654+ 0 ,
655+ _utf16CharPtrs[pos],
656+ (SQLINTEGER )size,
657+ &_vecLengthIndicator[pos][0 ])))
658+ {
659+ throw StatementException (_rStmt, " SQLBindParameter(std::vector<UTF16String>)" );
660+ }
661+ }
662+
584663 template <typename C>
585664 void bindImplContainerLOB (std::size_t pos, const C& val, Direction dir)
586665 {
@@ -859,7 +938,7 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
859938 typename T::const_iterator end = val.end ();
860939 for (; it != end; ++it)
861940 {
862- std::size_t sz = it->size ();
941+ std::size_t sz = it->size () * sizeof (T) ;
863942 if (sz > _maxFieldSize)
864943 throw LengthExceededException ();
865944
@@ -888,11 +967,13 @@ class ODBC_API Binder: public Poco::Data::AbstractBinder
888967 TimeMap _times;
889968 TimestampMap _timestamps;
890969 StringMap _strings;
970+ UTF16StringMap _utf16Strings;
891971
892972 DateVec _dateVec;
893973 TimeVec _timeVec;
894974 DateTimeVec _dateTimeVec;
895975 CharPtrVec _charPtrs;
976+ UTF16CharPtrVec _utf16CharPtrs;
896977 BoolPtrVec _boolPtrs;
897978 const TypeInfo* _pTypeInfo;
898979 SQLINTEGER _paramSetSize;
@@ -1241,6 +1322,24 @@ inline void Binder::bind(std::size_t pos, const std::list<std::string>& val, Dir
12411322 bindImplContainerString (pos, val, dir);
12421323}
12431324
1325+
1326+ inline void Binder::bind (std::size_t pos, const std::vector<UTF16String>& val, Direction dir)
1327+ {
1328+ bindImplContainerUTF16String (pos, val, dir);
1329+ }
1330+
1331+
1332+ inline void Binder::bind (std::size_t pos, const std::deque<UTF16String>& val, Direction dir)
1333+ {
1334+ bindImplContainerUTF16String (pos, val, dir);
1335+ }
1336+
1337+
1338+ inline void Binder::bind (std::size_t pos, const std::list<UTF16String>& val, Direction dir)
1339+ {
1340+ bindImplContainerUTF16String (pos, val, dir);
1341+ }
1342+
12441343inline void Binder::bind (std::size_t pos, const BLOB & val, Direction dir)
12451344{
12461345 bindImplLOB<BLOB >(pos, val, dir);
0 commit comments