Changeset 823 for trunk/pgmodule.c


Ignore:
Timestamp:
Feb 5, 2016, 4:35:34 PM (4 years ago)
Author:
cito
Message:

Raise the proper subclasses of DatabaseError?

Particularly, we raise IntegrityError? instead of ProgrammingError? for
duplicate keys. This also makes PyGreSQL more useable with SQLAlchemy.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/pgmodule.c

    r817 r823  
    12971297}
    12981298
     1299/* gets appropriate error type from sqlstate */
     1300static PyObject *
     1301get_error_type(const char *sqlstate)
     1302{
     1303        switch (sqlstate[0]) {
     1304                case '0':
     1305                        switch (sqlstate[1])
     1306                        {
     1307                                case 'A':
     1308                                        return NotSupportedError;
     1309                        }
     1310                        break;
     1311                case '2':
     1312                        switch (sqlstate[1])
     1313                        {
     1314                                case '0':
     1315                                case '1':
     1316                                        return ProgrammingError;
     1317                                case '2':
     1318                                        return DataError;
     1319                                case '3':
     1320                                        return IntegrityError;
     1321                                case '4':
     1322                                case '5':
     1323                                        return InternalError;
     1324                                case '6':
     1325                                case '7':
     1326                                case '8':
     1327                                        return OperationalError;
     1328                                case 'B':
     1329                                case 'D':
     1330                                case 'F':
     1331                                        return InternalError;
     1332                        }
     1333                        break;
     1334                case '3':
     1335                        switch (sqlstate[1])
     1336                        {
     1337                                case '4':
     1338                                        return OperationalError;
     1339                                case '8':
     1340                                case '9':
     1341                                case 'B':
     1342                                        return InternalError;
     1343                                case 'D':
     1344                                case 'F':
     1345                                        return ProgrammingError;
     1346                        }
     1347                        break;
     1348                case '4':
     1349                        switch (sqlstate[1])
     1350                        {
     1351                                case '0':
     1352                                        return OperationalError;
     1353                                case '2':
     1354                                case '4':
     1355                                        return ProgrammingError;
     1356                        }
     1357                        break;
     1358                case '5':
     1359                case 'H':
     1360                        return OperationalError;
     1361                case 'F':
     1362                case 'P':
     1363                case 'X':
     1364                        return InternalError;
     1365        }
     1366        return DatabaseError;
     1367}
     1368
    12991369/* sets database error with sqlstate attribute */
    13001370/* This should be used when raising a subclass of DatabaseError */
     
    13021372set_dberror(PyObject *type, const char *msg, PGresult *result)
    13031373{
    1304         PyObject *err = NULL;
    1305         PyObject *str;
    1306 
    1307         if (!(str = PyStr_FromString(msg)))
    1308                 err = NULL;
     1374        PyObject   *err_obj, *msg_obj, *sql_obj = NULL;
     1375
     1376        if (result)
     1377        {
     1378                char *sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
     1379                if (sqlstate)
     1380                {
     1381                        sql_obj = PyStr_FromStringAndSize(sqlstate, 5);
     1382                        type = get_error_type(sqlstate);
     1383                }
     1384        }
     1385        if (!sql_obj)
     1386        {
     1387                Py_INCREF(Py_None);
     1388                sql_obj = Py_None;
     1389        }
     1390        msg_obj = PyStr_FromString(msg);
     1391        err_obj = PyObject_CallFunctionObjArgs(type, msg_obj, NULL);
     1392        if (err_obj)
     1393        {
     1394                Py_DECREF(msg_obj);
     1395                PyObject_SetAttrString(err_obj, "sqlstate", sql_obj);
     1396                Py_DECREF(sql_obj);
     1397                PyErr_SetObject(type, err_obj);
     1398                Py_DECREF(err_obj);
     1399        }
    13091400        else
    13101401        {
    1311                 err = PyObject_CallFunctionObjArgs(type, str, NULL);
    1312                 Py_DECREF(str);
    1313         }
    1314         if (err)
    1315         {
    1316                 if (result)
    1317                 {
    1318                         char *sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
    1319                         str = sqlstate ? PyStr_FromStringAndSize(sqlstate, 5) : NULL;
    1320                 }
    1321                 else
    1322                         str = NULL;
    1323                 if (!str)
    1324                 {
    1325                         Py_INCREF(Py_None);
    1326                         str = Py_None;
    1327                 }
    1328                 PyObject_SetAttrString(err, "sqlstate", str);
    1329                 Py_DECREF(str);
    1330                 PyErr_SetObject(type, err);
    1331                 Py_DECREF(err);
    1332         }
    1333         else
    13341402                PyErr_SetString(type, msg);
     1403        }
    13351404}
    13361405
Note: See TracChangeset for help on using the changeset viewer.