TclODBCでnvarcharを使えるようにする
をテンプレートにして作成
[
Front page
] [
Page list
|
Search
|
Recent changes
|
RSS of recent changes
]
Start:
TclODBC2.3.1でMicrosoft SQL Server 2008に接続してnvarchar...
diff -BwE --strip-trailing-cr -ur tclodbc.old/database.c...
--- tclodbc.old/database.cxx 2004-03-21 07:14:19 +0900
+++ tclodbc.new/database.cxx 2017-03-27 09:39:55 +0900
@@ -293,7 +293,7 @@
if (objc < 4 || objc > 6) {
THROWSTR("wrong # args, should be eval ...
} else {
- TclSqlStatement stmt(*this, Tcl_GetString(objv[3]),
+ TclSqlStatement stmt(*this, objv[3],
useMultipleResultSets);
TclObj proc (objv[2]);
@@ -312,7 +312,7 @@
if (objc < 4 || objc > 6) {
THROWSTR("wrong # args, should be read ...
} else {
- TclSqlStatement stmt(*this, Tcl_GetString(objv[3]),
+ TclSqlStatement stmt(*this, objv[3],
useMultipleResultSets);
TclObj arraySpec (objv[2]);
@@ -331,7 +331,7 @@
if (objc < 2 || objc > 4) {
THROWSTR("wrong # args, should be sql [...
} else {
- TclSqlStatement stmt(*this, Tcl_GetString(objv[1]),
+ TclSqlStatement stmt(*this, objv[1],
useMultipleResultSets);
if (objc == 4) {
stmt.SetArgDefs(interp, objv[2]);
diff -BwE --strip-trailing-cr -ur tclodbc.old/statemnt.c...
--- tclodbc.old/statemnt.cxx 2004-03-21 07:14:19 +0900
+++ tclodbc.new/statemnt.cxx 2017-05-24 16:43:33 +0900
@@ -261,6 +261,10 @@
THROWOBJ(SqlErr(env, SQL_NULL_HDBC, stmt))
}
+ if (EncodedType(resultBuffer[i].fSqlType)) {
+ resultBuffer[i].cbValueMax *= 2;
+ }
+
// target type
resultBuffer[i].fTargetType = MapSqlType (resul...
@@ -562,7 +566,7 @@
// (1 for string null terminator, obligator...
char dummy;
while ((rc = SQLGetData(stmt, (UWORD) (i+1)...
- &dummy, resultBuffer[i].fTargetType == ...
+ &dummy, resultBuffer[i].fTargetType == ...
&(resultBuffer[i].cbValue))) == SQL_STI...
if (rc == SQL_ERROR) {
THROWOBJ(SqlErr(env, SQL_NULL_HDBC, stm...
@@ -598,7 +602,7 @@
// get buffer full of data
while ((rc = SQLGetData(stmt, i+1, ...
(char*) buffer,
- BUFSIZE + (resultBuffer[i].fTar...
+ BUFSIZE + (resultBuffer[i].fTar...
&(resultBuffer[i].cbValue))) ==...
if (rc == SQL_ERROR) {
THROWOBJ(SqlErr(env, SQL_NULL_H...
@@ -614,7 +618,7 @@
// finally, get the actual data
while ((rc = SQLGetData(stmt, i+1, resu...
(char*) element,
- resultBuffer[i].cbValue + 1,
+ resultBuffer[i].cbValue + 2,
&(resultBuffer[i].cbValue))) == SQL...
// set element length again. Some drivers return or...
@@ -625,8 +629,12 @@
}
}
- if (EncodedType(resultBuffer[i].fSqlType))
- element.Decode(pDb->Encoding());
+ if (EncodedType(resultBuffer[i].fSqlType)) {
+ Tcl_Encoding e = Tcl_GetEncoding(NULL, "unicode");
+ element.Decode(e);
+ Tcl_FreeEncoding(e);
+ }
+
row.appendElement(element);
}
}
@@ -721,11 +729,12 @@
useMultipleResultSets = multiSets;
- // encode TclObj to selected character set
- sql.Encode(db.Encoding());
+ int wsqllen;
+ SQLWCHAR *wsql;
+ wsql = (SQLWCHAR*)Tcl_GetUnicodeFromObj(sql, &wsqll...
// prepare statement
- while ((rc = SQLPrepare(stmt, (UCHAR*) sql.EncodedV...
+ while (((rc = SQLPrepareW(stmt, wsql, wsqllen))) ==...
if (rc == SQL_ERROR)
THROWOBJ(SqlErr(env, db.DBC(), stmt))
@@ -834,6 +843,12 @@
if (EncodedType(argDefBuffer[i].fSqlType))
sqlArg.Encode(pDb->Encoding());
+ if (EncodedType(argDefBuffer[i].fSqlType)) {
+ Tcl_Encoding e = Tcl_GetEncoding(NULL, "unicode");
+ sqlArg.Encode(e);
+ Tcl_FreeEncoding(e);
+ }
+
sqlarglen = sqlArg.EncodedLenght();
if (sqlarglen == 0) {
diff -BwE --strip-trailing-cr -ur tclodbc.old/strings.cx...
--- tclodbc.old/strings.cxx 2004-03-21 07:14:19 +0900
+++ tclodbc.new/strings.cxx 2012-01-24 11:58:48 +0900
@@ -110,7 +110,7 @@
// in the struct.
NumStr sqlType [] = {
- {19, NULL },
+ {22, NULL },
{SQL_BIGINT, "BIGINT" },
{SQL_BINARY, "BINARY" },
{SQL_BIT, "BIT" },
@@ -129,7 +129,10 @@
{SQL_TIMESTAMP, "TIMESTAMP" },
{SQL_TINYINT, "TINYINT" },
{SQL_VARBINARY, "VARBINARY" },
- {SQL_VARCHAR, "VARCHAR" }
+ {SQL_VARCHAR, "VARCHAR" },
+ {SQL_WCHAR, "WCHAR" },
+ {SQL_WVARCHAR, "WVARCHAR" },
+ {SQL_WLONGVARCHAR, "WLONGVARCHAR"}
};
NumStr attrDef [] = {
diff -BwE --strip-trailing-cr -ur tclodbc.old/tclodbc.cx...
--- tclodbc.old/tclodbc.cxx 2004-03-20 05:32:21 +0900
+++ tclodbc.new/tclodbc.cxx 2017-03-27 08:36:55 +0900
@@ -118,24 +118,24 @@
//
TclObj SqlErr (HENV env, HDBC dbc, HSTMT stmt) {
- char SqlMessage[SQL_MAX_MESSAGE_LENGTH];
- char SqlState[6];
+ SQLWCHAR SqlMessage[SQL_MAX_MESSAGE_LENGTH];
+ SQLWCHAR SqlState[6];
SDWORD NativeError;
SWORD Available;
RETCODE rc;
TclObj errObj;
- rc = SQLError(env, dbc, stmt,
- (UCHAR*) SqlState, &NativeError, (UCHAR*) S...
+ rc = SQLErrorW(env, dbc, stmt,
+ SqlState, &NativeError, SqlMessage,
SQL_MAX_MESSAGE_LENGTH-1, &Available);
// sql error object is a triple:
// {standard error code} {native error code} {error...
if (rc != SQL_ERROR) {
- errObj.appendElement(TclObj(SqlState));
+ errObj.appendElement(TclObj(Tcl_NewUnicodeObj((...
errObj.appendElement(TclObj(NativeError));
- errObj.appendElement(TclObj(SqlMessage,Availabl...
+ errObj.appendElement(TclObj(Tcl_NewUnicodeObj((...
} else {
errObj.appendElement("FATAL ERROR: Failed to re...
}
@@ -202,6 +202,9 @@
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
+ case SQL_WCHAR:
+ case SQL_WVARCHAR:
+ case SQL_WLONGVARCHAR:
return TRUE;
default:
return FALSE;
@@ -214,6 +217,13 @@
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
return SQL_C_BINARY;
+ case SQL_CHAR:
+ case SQL_VARCHAR:
+ case SQL_LONGVARCHAR:
+ case SQL_WCHAR:
+ case SQL_WVARCHAR:
+ case SQL_WLONGVARCHAR:
+ return SQL_C_WCHAR;
default:
return SQL_C_CHAR;
}
@@ -339,7 +348,7 @@
extern "C" {
_declspec(dllexport)
-Tclodbc_Init(Tcl_Interp *interp)
+int Tclodbc_Init(Tcl_Interp *interp)
{
#ifdef USE_TCL_STUBS
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
diff -BwE --strip-trailing-cr -ur tclodbc.old/tclodbc.hx...
--- tclodbc.old/tclodbc.hxx 2005-03-26 05:49:21 +0900
+++ tclodbc.new/tclodbc.hxx 2012-01-24 12:37:32 +0900
@@ -542,6 +542,8 @@
SWORD MapSqlType (SDWORD colType);
+BOOL UnicodeType (int i);
+
#ifdef _DEBUG
int tclodbc_validateNumStrArrays();
int tclodbc_validateStrToNumFunction();
このパッチでは、次の点を改良した。
+ UNICODE文字列型に対応した。
+ SQL文は全てunicode文字列として扱うことにした。(Tclの内...
+ varchar型のデータの取得に関しては従来どおり、database s...
+ エラーメッセージはUnicodeで取得して、そのままUTF-8に変...
+ Excelドライバの時でもUnicode文字が文字化けしないように...
**ダウンロード [#w0d8e76c]
-http://reddog.s35.xrea.com/software/tclodbc25-wchar-patc...
-http://reddog.s35.xrea.com/software/tclodbc25-wchar-patc...
-http://reddog.s35.xrea.com/software/tclodbc25-wchar-patc...
**雑感 [#p689b144]
TclODBCのソースコードが読みにくい。C++な上、Tcl7.6とソー...
**参考リンク [#z7ed9f86]
-http://sourceforge.net/projects/tclodbc
-http://msdn.microsoft.com/en-us/library/ms714177(VS.85)....
**コメントをどーぞ [#d131bb86]
- Excelで文字化けするので、これを発見したときには、すごい...
-- %%Excel側のデータはUnicodeなのにExcelのODBCドライバがS...
-- なんかできそうな気がしてきた -- reddog &new{2017-03-24...
-- なんかできた -- reddog &new{2017-03-27 (月) 10:36:45};
- 結局ADODBでやったらできたんですが、せっかくなので新しい...
#comment
----
[[CategoryTclTk]]
End:
TclODBC2.3.1でMicrosoft SQL Server 2008に接続してnvarchar...
diff -BwE --strip-trailing-cr -ur tclodbc.old/database.c...
--- tclodbc.old/database.cxx 2004-03-21 07:14:19 +0900
+++ tclodbc.new/database.cxx 2017-03-27 09:39:55 +0900
@@ -293,7 +293,7 @@
if (objc < 4 || objc > 6) {
THROWSTR("wrong # args, should be eval ...
} else {
- TclSqlStatement stmt(*this, Tcl_GetString(objv[3]),
+ TclSqlStatement stmt(*this, objv[3],
useMultipleResultSets);
TclObj proc (objv[2]);
@@ -312,7 +312,7 @@
if (objc < 4 || objc > 6) {
THROWSTR("wrong # args, should be read ...
} else {
- TclSqlStatement stmt(*this, Tcl_GetString(objv[3]),
+ TclSqlStatement stmt(*this, objv[3],
useMultipleResultSets);
TclObj arraySpec (objv[2]);
@@ -331,7 +331,7 @@
if (objc < 2 || objc > 4) {
THROWSTR("wrong # args, should be sql [...
} else {
- TclSqlStatement stmt(*this, Tcl_GetString(objv[1]),
+ TclSqlStatement stmt(*this, objv[1],
useMultipleResultSets);
if (objc == 4) {
stmt.SetArgDefs(interp, objv[2]);
diff -BwE --strip-trailing-cr -ur tclodbc.old/statemnt.c...
--- tclodbc.old/statemnt.cxx 2004-03-21 07:14:19 +0900
+++ tclodbc.new/statemnt.cxx 2017-05-24 16:43:33 +0900
@@ -261,6 +261,10 @@
THROWOBJ(SqlErr(env, SQL_NULL_HDBC, stmt))
}
+ if (EncodedType(resultBuffer[i].fSqlType)) {
+ resultBuffer[i].cbValueMax *= 2;
+ }
+
// target type
resultBuffer[i].fTargetType = MapSqlType (resul...
@@ -562,7 +566,7 @@
// (1 for string null terminator, obligator...
char dummy;
while ((rc = SQLGetData(stmt, (UWORD) (i+1)...
- &dummy, resultBuffer[i].fTargetType == ...
+ &dummy, resultBuffer[i].fTargetType == ...
&(resultBuffer[i].cbValue))) == SQL_STI...
if (rc == SQL_ERROR) {
THROWOBJ(SqlErr(env, SQL_NULL_HDBC, stm...
@@ -598,7 +602,7 @@
// get buffer full of data
while ((rc = SQLGetData(stmt, i+1, ...
(char*) buffer,
- BUFSIZE + (resultBuffer[i].fTar...
+ BUFSIZE + (resultBuffer[i].fTar...
&(resultBuffer[i].cbValue))) ==...
if (rc == SQL_ERROR) {
THROWOBJ(SqlErr(env, SQL_NULL_H...
@@ -614,7 +618,7 @@
// finally, get the actual data
while ((rc = SQLGetData(stmt, i+1, resu...
(char*) element,
- resultBuffer[i].cbValue + 1,
+ resultBuffer[i].cbValue + 2,
&(resultBuffer[i].cbValue))) == SQL...
// set element length again. Some drivers return or...
@@ -625,8 +629,12 @@
}
}
- if (EncodedType(resultBuffer[i].fSqlType))
- element.Decode(pDb->Encoding());
+ if (EncodedType(resultBuffer[i].fSqlType)) {
+ Tcl_Encoding e = Tcl_GetEncoding(NULL, "unicode");
+ element.Decode(e);
+ Tcl_FreeEncoding(e);
+ }
+
row.appendElement(element);
}
}
@@ -721,11 +729,12 @@
useMultipleResultSets = multiSets;
- // encode TclObj to selected character set
- sql.Encode(db.Encoding());
+ int wsqllen;
+ SQLWCHAR *wsql;
+ wsql = (SQLWCHAR*)Tcl_GetUnicodeFromObj(sql, &wsqll...
// prepare statement
- while ((rc = SQLPrepare(stmt, (UCHAR*) sql.EncodedV...
+ while (((rc = SQLPrepareW(stmt, wsql, wsqllen))) ==...
if (rc == SQL_ERROR)
THROWOBJ(SqlErr(env, db.DBC(), stmt))
@@ -834,6 +843,12 @@
if (EncodedType(argDefBuffer[i].fSqlType))
sqlArg.Encode(pDb->Encoding());
+ if (EncodedType(argDefBuffer[i].fSqlType)) {
+ Tcl_Encoding e = Tcl_GetEncoding(NULL, "unicode");
+ sqlArg.Encode(e);
+ Tcl_FreeEncoding(e);
+ }
+
sqlarglen = sqlArg.EncodedLenght();
if (sqlarglen == 0) {
diff -BwE --strip-trailing-cr -ur tclodbc.old/strings.cx...
--- tclodbc.old/strings.cxx 2004-03-21 07:14:19 +0900
+++ tclodbc.new/strings.cxx 2012-01-24 11:58:48 +0900
@@ -110,7 +110,7 @@
// in the struct.
NumStr sqlType [] = {
- {19, NULL },
+ {22, NULL },
{SQL_BIGINT, "BIGINT" },
{SQL_BINARY, "BINARY" },
{SQL_BIT, "BIT" },
@@ -129,7 +129,10 @@
{SQL_TIMESTAMP, "TIMESTAMP" },
{SQL_TINYINT, "TINYINT" },
{SQL_VARBINARY, "VARBINARY" },
- {SQL_VARCHAR, "VARCHAR" }
+ {SQL_VARCHAR, "VARCHAR" },
+ {SQL_WCHAR, "WCHAR" },
+ {SQL_WVARCHAR, "WVARCHAR" },
+ {SQL_WLONGVARCHAR, "WLONGVARCHAR"}
};
NumStr attrDef [] = {
diff -BwE --strip-trailing-cr -ur tclodbc.old/tclodbc.cx...
--- tclodbc.old/tclodbc.cxx 2004-03-20 05:32:21 +0900
+++ tclodbc.new/tclodbc.cxx 2017-03-27 08:36:55 +0900
@@ -118,24 +118,24 @@
//
TclObj SqlErr (HENV env, HDBC dbc, HSTMT stmt) {
- char SqlMessage[SQL_MAX_MESSAGE_LENGTH];
- char SqlState[6];
+ SQLWCHAR SqlMessage[SQL_MAX_MESSAGE_LENGTH];
+ SQLWCHAR SqlState[6];
SDWORD NativeError;
SWORD Available;
RETCODE rc;
TclObj errObj;
- rc = SQLError(env, dbc, stmt,
- (UCHAR*) SqlState, &NativeError, (UCHAR*) S...
+ rc = SQLErrorW(env, dbc, stmt,
+ SqlState, &NativeError, SqlMessage,
SQL_MAX_MESSAGE_LENGTH-1, &Available);
// sql error object is a triple:
// {standard error code} {native error code} {error...
if (rc != SQL_ERROR) {
- errObj.appendElement(TclObj(SqlState));
+ errObj.appendElement(TclObj(Tcl_NewUnicodeObj((...
errObj.appendElement(TclObj(NativeError));
- errObj.appendElement(TclObj(SqlMessage,Availabl...
+ errObj.appendElement(TclObj(Tcl_NewUnicodeObj((...
} else {
errObj.appendElement("FATAL ERROR: Failed to re...
}
@@ -202,6 +202,9 @@
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
+ case SQL_WCHAR:
+ case SQL_WVARCHAR:
+ case SQL_WLONGVARCHAR:
return TRUE;
default:
return FALSE;
@@ -214,6 +217,13 @@
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
return SQL_C_BINARY;
+ case SQL_CHAR:
+ case SQL_VARCHAR:
+ case SQL_LONGVARCHAR:
+ case SQL_WCHAR:
+ case SQL_WVARCHAR:
+ case SQL_WLONGVARCHAR:
+ return SQL_C_WCHAR;
default:
return SQL_C_CHAR;
}
@@ -339,7 +348,7 @@
extern "C" {
_declspec(dllexport)
-Tclodbc_Init(Tcl_Interp *interp)
+int Tclodbc_Init(Tcl_Interp *interp)
{
#ifdef USE_TCL_STUBS
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
diff -BwE --strip-trailing-cr -ur tclodbc.old/tclodbc.hx...
--- tclodbc.old/tclodbc.hxx 2005-03-26 05:49:21 +0900
+++ tclodbc.new/tclodbc.hxx 2012-01-24 12:37:32 +0900
@@ -542,6 +542,8 @@
SWORD MapSqlType (SDWORD colType);
+BOOL UnicodeType (int i);
+
#ifdef _DEBUG
int tclodbc_validateNumStrArrays();
int tclodbc_validateStrToNumFunction();
このパッチでは、次の点を改良した。
+ UNICODE文字列型に対応した。
+ SQL文は全てunicode文字列として扱うことにした。(Tclの内...
+ varchar型のデータの取得に関しては従来どおり、database s...
+ エラーメッセージはUnicodeで取得して、そのままUTF-8に変...
+ Excelドライバの時でもUnicode文字が文字化けしないように...
**ダウンロード [#w0d8e76c]
-http://reddog.s35.xrea.com/software/tclodbc25-wchar-patc...
-http://reddog.s35.xrea.com/software/tclodbc25-wchar-patc...
-http://reddog.s35.xrea.com/software/tclodbc25-wchar-patc...
**雑感 [#p689b144]
TclODBCのソースコードが読みにくい。C++な上、Tcl7.6とソー...
**参考リンク [#z7ed9f86]
-http://sourceforge.net/projects/tclodbc
-http://msdn.microsoft.com/en-us/library/ms714177(VS.85)....
**コメントをどーぞ [#d131bb86]
- Excelで文字化けするので、これを発見したときには、すごい...
-- %%Excel側のデータはUnicodeなのにExcelのODBCドライバがS...
-- なんかできそうな気がしてきた -- reddog &new{2017-03-24...
-- なんかできた -- reddog &new{2017-03-27 (月) 10:36:45};
- 結局ADODBでやったらできたんですが、せっかくなので新しい...
#comment
----
[[CategoryTclTk]]
Page:
HTML convert time: 0.003 sec.