Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0b6c665

Browse filesBrowse files
authored
Refactoring JSON support (PyMySQL#312)
1 parent 4b40c8c commit 0b6c665
Copy full SHA for 0b6c665

File tree

Expand file treeCollapse file tree

2 files changed

+60
-51
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+60
-51
lines changed

‎MySQLdb/_mysql.c

Copy file name to clipboardExpand all lines: MySQLdb/_mysql.c
+56-50Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,13 @@ _mysql_ResultObject_Initialize(
302302
long flags = fields[i].flags;
303303
PyObject *fun2=NULL;
304304
int j, n2=PySequence_Size(fun);
305-
if (fields[i].charsetnr != 63) { /* maaagic */
306-
flags &= ~BINARY_FLAG;
307-
} else {
305+
// BINARY_FLAG means ***_bin collation is used.
306+
// To distinguish text and binary, we shoud use charsetnr==63 (binary).
307+
// But we abuse BINARY_FLAG for historical reason.
308+
if (fields[i].charsetnr == 63) {
308309
flags |= BINARY_FLAG;
310+
} else {
311+
flags &= ~BINARY_FLAG;
309312
}
310313
for (j=0; j<n2; j++) {
311314
PyObject *t = PySequence_GetItem(fun, j);
@@ -1098,58 +1101,61 @@ _mysql_field_to_python(
10981101
MYSQL_FIELD *field,
10991102
const char *encoding)
11001103
{
1101-
PyObject *v;
1102-
#ifdef IS_PY3K
1103-
int field_type = field->type;
1104-
// Return bytes for binary and string types.
1105-
int binary = 0;
1106-
if (field_type == FIELD_TYPE_TINY_BLOB ||
1107-
field_type == FIELD_TYPE_MEDIUM_BLOB ||
1108-
field_type == FIELD_TYPE_LONG_BLOB ||
1109-
field_type == FIELD_TYPE_BLOB ||
1110-
field_type == FIELD_TYPE_VAR_STRING ||
1111-
field_type == FIELD_TYPE_STRING ||
1112-
field_type == FIELD_TYPE_GEOMETRY ||
1113-
field_type == FIELD_TYPE_BIT) {
1114-
binary = 1;
1104+
if (rowitem == NULL) {
1105+
Py_RETURN_NONE;
11151106
}
1116-
#endif
1117-
if (rowitem) {
1118-
if (converter == (PyObject*)&PyUnicode_Type) {
1119-
if (encoding == utf8) {
1120-
//fprintf(stderr, "decoding with utf8!\n");
1121-
v = PyUnicode_DecodeUTF8(rowitem, length, NULL);
1122-
} else {
1123-
//fprintf(stderr, "decoding with %s\n", encoding);
1124-
v = PyUnicode_Decode(rowitem, length, encoding, NULL);
1125-
}
1126-
}
1127-
else if (converter == (PyObject*)&PyBytes_Type || converter == Py_None) {
1128-
//fprintf(stderr, "decoding with bytes\n", encoding);
1129-
v = PyBytes_FromStringAndSize(rowitem, length);
1130-
}
1131-
else if (converter == (PyObject*)&PyInt_Type) {
1132-
//fprintf(stderr, "decoding with int\n", encoding);
1133-
v = PyInt_FromString(rowitem, NULL, 10);
1107+
1108+
// Fast paths for int, string and binary.
1109+
if (converter == (PyObject*)&PyUnicode_Type) {
1110+
if (encoding == utf8) {
1111+
//fprintf(stderr, "decoding with utf8!\n");
1112+
return PyUnicode_DecodeUTF8(rowitem, length, NULL);
1113+
} else {
1114+
//fprintf(stderr, "decoding with %s\n", encoding);
1115+
return PyUnicode_Decode(rowitem, length, encoding, NULL);
11341116
}
1135-
else {
1136-
//fprintf(stderr, "decoding with callback\n");
1137-
//PyObject_Print(converter, stderr, 0);
1138-
//fprintf(stderr, "\n");
1139-
v = PyObject_CallFunction(converter,
1117+
}
1118+
if (converter == (PyObject*)&PyBytes_Type || converter == Py_None) {
1119+
//fprintf(stderr, "decoding with bytes\n", encoding);
1120+
return PyBytes_FromStringAndSize(rowitem, length);
1121+
}
1122+
if (converter == (PyObject*)&PyInt_Type) {
1123+
//fprintf(stderr, "decoding with int\n", encoding);
1124+
return PyInt_FromString(rowitem, NULL, 10);
1125+
}
1126+
1127+
//fprintf(stderr, "decoding with callback\n");
1128+
//PyObject_Print(converter, stderr, 0);
1129+
//fprintf(stderr, "\n");
11401130
#ifdef IS_PY3K
1141-
binary ? "y#" : "s#",
1131+
int binary;
1132+
switch (field->type) {
1133+
case FIELD_TYPE_TINY_BLOB:
1134+
case FIELD_TYPE_MEDIUM_BLOB:
1135+
case FIELD_TYPE_LONG_BLOB:
1136+
case FIELD_TYPE_BLOB:
1137+
case FIELD_TYPE_VAR_STRING:
1138+
case FIELD_TYPE_STRING:
1139+
case FIELD_TYPE_GEOMETRY:
1140+
case FIELD_TYPE_BIT:
1141+
#ifdef FIELD_TYPE_JSON
1142+
case FIELD_TYPE_JSON:
11421143
#else
1143-
"s#",
1144+
case 245: // JSON
11441145
#endif
1145-
rowitem,
1146-
(int)length);
1147-
}
1148-
} else {
1149-
Py_INCREF(Py_None);
1150-
v = Py_None;
1146+
// Call converter with bytes
1147+
binary = 1;
1148+
default: // e.g. FIELD_TYPE_DATETIME, etc.
1149+
// Call converter with unicode string
1150+
binary = 0;
11511151
}
1152-
return v;
1152+
return PyObject_CallFunction(converter,
1153+
binary ? "y#" : "s#",
1154+
rowitem, (int)length);
1155+
#else
1156+
return PyObject_CallFunction(converter,
1157+
"s#", rowitem, (int)length);
1158+
#endif
11531159
}
11541160

11551161
static PyObject *
@@ -1226,7 +1232,7 @@ _mysql_row_to_dict_old(
12261232
unsigned int n, i;
12271233
unsigned long *length;
12281234
PyObject *r, *c;
1229-
MYSQL_FIELD *fields;
1235+
MYSQL_FIELD *fields;
12301236

12311237
n = mysql_num_fields(self->result);
12321238
if (!(r = PyDict_New())) return NULL;

‎MySQLdb/connections.py

Copy file name to clipboardExpand all lines: MySQLdb/connections.py
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,11 @@ def unicode_literal(u, dummy=None):
183183

184184
if use_unicode:
185185
for t in (FIELD_TYPE.STRING, FIELD_TYPE.VAR_STRING, FIELD_TYPE.VARCHAR, FIELD_TYPE.TINY_BLOB,
186-
FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.LONG_BLOB, FIELD_TYPE.BLOB, FIELD_TYPE.JSON):
186+
FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.LONG_BLOB, FIELD_TYPE.BLOB):
187187
self.converter[t] = _bytes_or_str
188+
# Unlike other string/blob types, JSON is always text.
189+
# MySQL may return JSON with charset==binary.
190+
self.converter[FIELD_TYPE.JSON] = unicode
188191

189192
self.encoders[unicode] = unicode_literal
190193
self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.