/***************************************************************************** Copyright (C) 2018-2020 Georg Richter and MariaDB Corporation AB This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not see or write to the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor, Boston, MA 02110, USA ******************************************************************************/ #include static void Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self); /* todo: move information into docs subdirectory */ static char mariadb_fieldinfo_documentation[] = "Returns a MariaDB field information object"; static PyObject * Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self, PyObject *args); static PyObject * Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self, PyObject *args); static PyMethodDef Mariadb_Fieldinfo_Methods[] = { {"type", (PyCFunction)Mariadb_Fieldinfo_gettype, METH_VARARGS, "Returns type information for the given field"}, {"flag", (PyCFunction)Mariadb_Fieldinfo_getflag, METH_VARARGS, "Returns flag information for the given field"}, {NULL} /* always last */ }; static struct PyMemberDef Mariadb_Fieldinfo_Members[] = { {NULL} }; static void Mariadb_Fieldinfo_dealloc(Mariadb_Fieldinfo *self) { Py_TYPE(self)->tp_free((PyObject*)self); } static int Mariadb_Fieldinfo_traverse(Mariadb_Fieldinfo *self, visitproc visit, void *arg) { return 0; } PyTypeObject Mariadb_Fieldinfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) "mariadb.fieldinfo", sizeof(Mariadb_Fieldinfo), 0, (destructor)Mariadb_Fieldinfo_dealloc, /* tp_dealloc */ 0, /*tp_print*/ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /*tp_compare*/ 0, /* tp_repr */ /* Method suites for standard classes */ 0, /* (PyNumberMethods *) tp_as_number */ 0, /* (PySequenceMethods *) tp_as_sequence */ 0, /* (PyMappingMethods *) tp_as_mapping */ /* More standard operations (here for binary compatibility) */ 0, /* (hashfunc) tp_hash */ 0, /* (ternaryfunc) tp_call */ 0, /* (reprfunc) tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ /* Functions to access object as input/output buffer */ 0, /* (PyBufferProcs *) tp_as_buffer */ /* (tp_flags) Flags to define presence of optional/expanded features */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, mariadb_fieldinfo_documentation, /* tp_doc Documentation string */ /* call function for all accessible objects */ (traverseproc)Mariadb_Fieldinfo_traverse,/* tp_traverse */ /* delete references to contained objects */ 0, /* tp_clear */ /* rich comparisons */ 0, /* (richcmpfunc) tp_richcompare */ /* weak reference enabler */ 0, /* (long) tp_weaklistoffset */ /* Iterators */ 0, /* (getiterfunc) tp_iter */ 0, /* (iternextfunc) tp_iternext */ /* Attribute descriptor and subclassing stuff */ (struct PyMethodDef *)Mariadb_Fieldinfo_Methods, /* tp_methods */ (struct PyMemberDef *)Mariadb_Fieldinfo_Members, /* tp_members */ 0, /* (struct getsetlist *) tp_getset; */ 0, /* (struct _typeobject *) tp_base; */ 0, /* (PyObject *) tp_dict */ 0, /* (descrgetfunc) tp_descr_get */ 0, /* (descrsetfunc) tp_descr_set */ 0, /* (long) tp_dictoffset */ 0, /* (initproc)Mariadb_Fieldinfo_initialize, tp_init */ PyType_GenericAlloc, //NULL, /* tp_alloc */ PyType_GenericNew, //NULL, /* tp_new */ NULL, /* tp_free Low-level free-memory routine */ 0, /* (PyObject *) tp_bases */ 0, /* (PyObject *) tp_mro method resolution order */ 0, /* (PyObject *) tp_defined */ }; struct st_type_mapping { enum enum_field_types type; const char *name; } type_code[]= { {MYSQL_TYPE_DECIMAL, "DECIMAL"}, {MYSQL_TYPE_TINY, "TINY"}, {MYSQL_TYPE_SHORT, "SHORT"}, {MYSQL_TYPE_LONG, "LONG"}, {MYSQL_TYPE_FLOAT, "FLOAT"}, {MYSQL_TYPE_DOUBLE, "DOUBLE"}, {MYSQL_TYPE_NULL, "NULL"}, {MYSQL_TYPE_TIMESTAMP, "TIMESTAMP"}, {MYSQL_TYPE_LONGLONG, "LONGLONG"}, {MYSQL_TYPE_INT24, "INT24"}, {MYSQL_TYPE_DATE, "DATE"}, {MYSQL_TYPE_TIME, "TIME"}, {MYSQL_TYPE_DATETIME, "DATETIME"}, {MYSQL_TYPE_YEAR, "YEAR"}, {MYSQL_TYPE_NEWDATE, "NEWDATE"}, {MYSQL_TYPE_VARCHAR, "VARCHAR"}, {MYSQL_TYPE_BIT, "BIT"}, {MYSQL_TYPE_JSON, "JSON"}, {MYSQL_TYPE_NEWDECIMAL, "NEWDECIMAL"}, {MYSQL_TYPE_ENUM, "ENUM"}, {MYSQL_TYPE_SET, "SET"}, {MYSQL_TYPE_TINY_BLOB, "BLOB"}, {MYSQL_TYPE_MEDIUM_BLOB, "MEDIUM_BLOB"}, {MYSQL_TYPE_LONG_BLOB, "LONG_BLOB"}, {MYSQL_TYPE_BLOB, "BLOB"}, {MYSQL_TYPE_VAR_STRING, "VAR_STRING"}, {MYSQL_TYPE_STRING, "STRING"}, {MYSQL_TYPE_GEOMETRY, "GEOMETRY"}, {0, NULL} }; static PyObject *Mariadb_Fieldinfo_gettype(Mariadb_Fieldinfo *self, PyObject *args) { uint16_t i=0; enum enum_field_types field_type; PyObject *data= NULL; PyObject *type= NULL; if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &data)) { return NULL; } if (PyTuple_Size(data) != 8) { mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0, "Parameter isn't a (valid) description sequence"); return NULL; } type= PyTuple_GetItem(data, 1); if (Py_TYPE(type) != &PyLong_Type) { mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0, "Parameter isn't a (valid) description sequence"); return NULL; } field_type= PyLong_AsLong(type); while(type_code[i].name) { if (type_code[i].type == field_type) { return PyUnicode_FromString(type_code[i].name); } i++; } return PyUnicode_FromString("UNKNOWN"); } struct st_flag { uint32_t flag; const char *name; } flag_name[]= { {NOT_NULL_FLAG, "NOT_NULL"}, {PRI_KEY_FLAG, "PRIMARY_KEY"}, {UNIQUE_KEY_FLAG, "UNIQUE_KEY"}, {MULTIPLE_KEY_FLAG, "PART_KEY"}, {BLOB_FLAG, "BLOB"}, {UNSIGNED_FLAG, "UNSIGNED"}, {ZEROFILL_FLAG, "ZEROFILL"}, {BINARY_FLAG, "BINARY"}, {ENUM_FLAG, "NUMERIC"}, {AUTO_INCREMENT_FLAG, "AUTO_INCREMENT"}, {TIMESTAMP_FLAG, "TIMESTAMP"}, {SET_FLAG, "SET"}, {NO_DEFAULT_VALUE_FLAG, "NO_DEFAULT"}, {ON_UPDATE_NOW_FLAG, "UPDATE_TIMESTAMP"}, {NUM_FLAG, "NUMERIC"}, {0, NULL} }; static PyObject * Mariadb_Fieldinfo_getflag(Mariadb_Fieldinfo *self, PyObject *args) { uint16_t i=0; unsigned long flag_val= 0; PyObject *data= NULL; PyObject *flag= NULL; char str_flag[512]= {0}; char *p, *end; if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &data)) { return NULL; } if (PyTuple_Size(data) != 8) { mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0, "Parameter isn't a (valid) description sequence"); return NULL; } flag= PyTuple_GetItem(data, 7); if (Py_TYPE(flag) != &PyLong_Type) { mariadb_throw_exception(NULL, Mariadb_InterfaceError, 0, "Parameter isn't a (valid) description sequence"); return NULL; } flag_val= PyLong_AsUnsignedLong(flag); if (!flag_val) { goto end; } p= &str_flag[0]; end= p + 511; while(flag_name[i].name) { if (flag_val & flag_name[i].flag) { if (str_flag[0] && end - p > 3) { strcpy(p, " | "); p+= 3; } if ((ssize_t)strlen(flag_name[i].name) < end - p) { strcpy(p, flag_name[i].name); p+= strlen(flag_name[i].name); } } i++; } *p= 0; end: return PyUnicode_FromString(str_flag); }