@@ -37,6 +37,8 @@ PERFORMANCE OF THIS SOFTWARE.
37
37
#include "Python.h"
38
38
#if PY_MAJOR_VERSION >= 3
39
39
#define IS_PY3K
40
+ #define PyInt_Type PyLong_Type
41
+ #define PyInt_FromString PyLong_FromString
40
42
#define PyInt_FromLong (n ) PyLong_FromLong(n)
41
43
#define PyInt_Check (n ) PyLong_Check(n)
42
44
#define PyInt_AS_LONG (n ) PyLong_AS_LONG(n)
@@ -87,6 +89,7 @@ typedef struct {
87
89
int use ;
88
90
char has_next ;
89
91
PyObject * converter ;
92
+ const char * encoding ;
90
93
} _mysql_ResultObject ;
91
94
92
95
extern PyTypeObject _mysql_ResultObject_Type ;
@@ -203,6 +206,25 @@ _mysql_Exception(_mysql_ConnectionObject *c)
203
206
return NULL ;
204
207
}
205
208
209
+ static const char * utf8 = "utf8" ;
210
+
211
+ static const char *
212
+ _get_encoding (MYSQL * mysql )
213
+ {
214
+ MY_CHARSET_INFO cs ;
215
+ mysql_get_character_set_info (mysql , & cs );
216
+ if (strncmp (utf8 , cs .csname , 4 ) == 0 ) { // utf8, utf8mb3, utf8mb4
217
+ return utf8 ;
218
+ }
219
+ else if (strncmp ("koi8r" , cs .csname , 5 ) == 0 ) {
220
+ return "koi8_r" ;
221
+ }
222
+ else if (strncmp ("koi8u" , cs .csname , 5 ) == 0 ) {
223
+ return "koi8_u" ;
224
+ }
225
+ return cs .csname ;
226
+ }
227
+
206
228
static char _mysql_thread_safe__doc__ [] =
207
229
"Indicates whether the client is compiled as thread-safe." ;
208
230
@@ -251,6 +273,9 @@ _mysql_ResultObject_Initialize(
251
273
self -> result = result ;
252
274
self -> has_next = (char )mysql_more_results (& (conn -> connection ));
253
275
Py_END_ALLOW_THREADS ;
276
+
277
+ self -> encoding = _get_encoding (& (conn -> connection ));
278
+ //fprintf(stderr, "encoding=%s\n", self->encoding);
254
279
if (!result ) {
255
280
if (mysql_errno (& (conn -> connection ))) {
256
281
_mysql_Exception (conn );
@@ -289,6 +314,8 @@ _mysql_ResultObject_Initialize(
289
314
int j , n2 = PySequence_Size (fun );
290
315
if (fields [i ].charsetnr != 63 ) { /* maaagic */
291
316
flags &= ~BINARY_FLAG ;
317
+ } else {
318
+ flags |= BINARY_FLAG ;
292
319
}
293
320
for (j = 0 ; j < n2 ; j ++ ) {
294
321
PyObject * t = PySequence_GetItem (fun , j );
@@ -943,8 +970,6 @@ _mysql_string_literal(
943
970
return (str );
944
971
}
945
972
946
- static PyObject * _mysql_NULL ;
947
-
948
973
static PyObject *
949
974
_escape_item (
950
975
PyObject * self ,
@@ -1011,28 +1036,21 @@ _mysql_ResultObject_describe(
1011
1036
{
1012
1037
PyObject * d ;
1013
1038
MYSQL_FIELD * fields ;
1014
- MY_CHARSET_INFO cs ;
1015
- int isutf8 = 0 ;
1016
1039
unsigned int i , n ;
1017
1040
1018
1041
check_result_connection (self );
1019
1042
1020
- mysql_get_character_set_info (& result_connection (self )-> connection , & cs );
1021
- if (strncmp ("utf8" , cs .name , 4 ) == 0 ) { // utf8, utf8mb3, utf8mb4
1022
- isutf8 = 1 ;
1023
- }
1024
-
1025
1043
n = mysql_num_fields (self -> result );
1026
1044
fields = mysql_fetch_fields (self -> result );
1027
1045
if (!(d = PyTuple_New (n ))) return NULL ;
1028
1046
for (i = 0 ; i < n ; i ++ ) {
1029
1047
PyObject * t ;
1030
1048
#ifdef IS_PY3K
1031
1049
PyObject * name ;
1032
- if (isutf8 ) {
1050
+ if (self -> encoding == utf8 ) {
1033
1051
name = PyUnicode_DecodeUTF8 (fields [i ].name , fields [i ].name_length , "replace" );
1034
1052
} else {
1035
- name = PyUnicode_Decode (fields [i ].name , fields [i ].name_length , cs . name , "replace" );
1053
+ name = PyUnicode_Decode (fields [i ].name , fields [i ].name_length , self -> encoding , "replace" );
1036
1054
}
1037
1055
if (name == NULL ) {
1038
1056
goto error ;
@@ -1089,9 +1107,10 @@ _mysql_ResultObject_field_flags(
1089
1107
static PyObject *
1090
1108
_mysql_field_to_python (
1091
1109
PyObject * converter ,
1092
- char * rowitem ,
1110
+ const char * rowitem ,
1093
1111
unsigned long length ,
1094
- MYSQL_FIELD * field )
1112
+ MYSQL_FIELD * field ,
1113
+ const char * encoding )
1095
1114
{
1096
1115
PyObject * v ;
1097
1116
#ifdef IS_PY3K
@@ -1110,7 +1129,27 @@ _mysql_field_to_python(
1110
1129
}
1111
1130
#endif
1112
1131
if (rowitem ) {
1113
- if (converter != Py_None ) {
1132
+ if (converter == (PyObject * )& PyUnicode_Type ) {
1133
+ if (encoding == utf8 ) {
1134
+ //fprintf(stderr, "decoding with utf8!\n");
1135
+ v = PyUnicode_DecodeUTF8 (rowitem , length , NULL );
1136
+ } else {
1137
+ //fprintf(stderr, "decoding with %s\n", encoding);
1138
+ v = PyUnicode_Decode (rowitem , length , encoding , NULL );
1139
+ }
1140
+ }
1141
+ else if (converter == (PyObject * )& PyBytes_Type ) {
1142
+ //fprintf(stderr, "decoding with bytes\n", encoding);
1143
+ v = PyBytes_FromStringAndSize (rowitem , length );
1144
+ }
1145
+ else if (converter == (PyObject * )& PyInt_Type ) {
1146
+ //fprintf(stderr, "decoding with int\n", encoding);
1147
+ v = PyInt_FromString (rowitem , NULL , 10 );
1148
+ }
1149
+ else if (converter != Py_None ) {
1150
+ //fprintf(stderr, "decoding with callback\n");
1151
+ //PyObject_Print(converter, stderr, 0);
1152
+ //fprintf(stderr, "\n");
1114
1153
v = PyObject_CallFunction (converter ,
1115
1154
#ifdef IS_PY3K
1116
1155
binary ? "y#" : "s#" ,
@@ -1120,6 +1159,7 @@ _mysql_field_to_python(
1120
1159
rowitem ,
1121
1160
(int )length );
1122
1161
} else {
1162
+ //fprintf(stderr, "converter=None\n");
1123
1163
#ifdef IS_PY3K
1124
1164
if (!binary ) {
1125
1165
v = PyUnicode_FromStringAndSize (rowitem , (int )length );
@@ -1153,7 +1193,7 @@ _mysql_row_to_tuple(
1153
1193
for (i = 0 ; i < n ; i ++ ) {
1154
1194
PyObject * v ;
1155
1195
c = PyTuple_GET_ITEM (self -> converter , i );
1156
- v = _mysql_field_to_python (c , row [i ], length [i ], & fields [i ]);
1196
+ v = _mysql_field_to_python (c , row [i ], length [i ], & fields [i ], self -> encoding );
1157
1197
if (!v ) goto error ;
1158
1198
PyTuple_SET_ITEM (r , i , v );
1159
1199
}
@@ -1180,7 +1220,7 @@ _mysql_row_to_dict(
1180
1220
for (i = 0 ; i < n ; i ++ ) {
1181
1221
PyObject * v ;
1182
1222
c = PyTuple_GET_ITEM (self -> converter , i );
1183
- v = _mysql_field_to_python (c , row [i ], length [i ], & fields [i ]);
1223
+ v = _mysql_field_to_python (c , row [i ], length [i ], & fields [i ], self -> encoding );
1184
1224
if (!v ) goto error ;
1185
1225
if (!PyMapping_HasKeyString (r , fields [i ].name )) {
1186
1226
PyMapping_SetItemString (r , fields [i ].name , v );
@@ -1219,7 +1259,7 @@ _mysql_row_to_dict_old(
1219
1259
for (i = 0 ; i < n ; i ++ ) {
1220
1260
PyObject * v ;
1221
1261
c = PyTuple_GET_ITEM (self -> converter , i );
1222
- v = _mysql_field_to_python (c , row [i ], length [i ], & fields [i ]);
1262
+ v = _mysql_field_to_python (c , row [i ], length [i ], & fields [i ], self -> encoding );
1223
1263
if (!v ) goto error ;
1224
1264
{
1225
1265
int len = 0 ;
@@ -1422,8 +1462,7 @@ _mysql_ConnectionObject_set_character_set(
1422
1462
err = mysql_set_character_set (& (self -> connection ), s );
1423
1463
Py_END_ALLOW_THREADS
1424
1464
if (err ) return _mysql_Exception (self );
1425
- Py_INCREF (Py_None );
1426
- return Py_None ;
1465
+ Py_RETURN_NONE ;
1427
1466
}
1428
1467
1429
1468
#if MYSQL_VERSION_ID >= 50010
@@ -2634,12 +2673,10 @@ init_mysql(void)
2634
2673
_mysql_ConnectionObject_Type .ob_type = & PyType_Type ;
2635
2674
_mysql_ResultObject_Type .ob_type = & PyType_Type ;
2636
2675
#endif
2637
- #if PY_VERSION_HEX >= 0x02020000
2638
2676
_mysql_ConnectionObject_Type .tp_alloc = PyType_GenericAlloc ;
2639
2677
_mysql_ConnectionObject_Type .tp_new = PyType_GenericNew ;
2640
2678
_mysql_ResultObject_Type .tp_alloc = PyType_GenericAlloc ;
2641
2679
_mysql_ResultObject_Type .tp_new = PyType_GenericNew ;
2642
- #endif
2643
2680
#ifdef IS_PY3K
2644
2681
if (PyType_Ready (& _mysql_ConnectionObject_Type ) < 0 )
2645
2682
return NULL ;
0 commit comments