File: _kicore_create_drop_db.c

package info (click to toggle)
python-kinterbasdb 3.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 2,432 kB
  • ctags: 1,830
  • sloc: ansic: 16,803; python: 3,514; makefile: 63; sh: 22
file content (144 lines) | stat: -rw-r--r-- 4,457 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* KInterbasDB Python Package - Implementation of SQL Statement Execution, etc.
 *
 * Version 3.3
 *
 * The following contributors hold Copyright (C) over their respective
 * portions of code (see license.txt for details):
 *
 * [Original Author (maintained through version 2.0-0.3.1):]
 *   1998-2001 [alex]  Alexander Kuznetsov   <alexan@users.sourceforge.net>
 * [Maintainers (after version 2.0-0.3.1):]
 *   2001-2002 [maz]   Marek Isalski         <kinterbasdb@maz.nu>
 *   2002-2007 [dsr]   David Rushby          <woodsplitter@rocketmail.com>
 * [Contributors:]
 *   2001      [eac]   Evgeny A. Cherkashin  <eugeneai@icc.ru>
 *   2001-2002 [janez] Janez Jere            <janez.jere@void.si>
 */

static PyObject *pyob_create_database(PyObject *self, PyObject *args) {
  CConnection *con = NULL;
  char *sql = NULL;
  Py_ssize_t sql_len = -1;
  short dialect = 0;

  if (!PyArg_ParseTuple(args, "s#|h", &sql, &sql_len, &dialect)) { goto fail; }

  if (!_check_statement_length(sql_len)) { goto fail; }

  /* A negative value for the dialect is not acceptable because the IB/FB API
   * requires an UNSIGNED SHORT. */
  if (dialect < 0) {
    raise_exception(ProgrammingError, "connection dialect must be > 0");
    goto fail;
  }

  con = Connection_create();
  if (con == NULL) { goto fail; }
  assert (con->main_trans == NULL);

  /* conn->dialect is set to a default value in the Connection_create
   * function, so we only need to change it if we received a dialect argument
   * to this function. */
  if (dialect > 0) {
    con->dialect = (unsigned short) dialect;
  }
  assert (con->dialect > 0);


  {
    isc_tr_handle unused_trans_handle = NULL_TRANS_HANDLE;

    LEAVE_GIL_WITHOUT_AFFECTING_DB
    ENTER_GDAL_WITHOUT_LEAVING_PYTHON
    ENTER_GCDL_WITHOUT_LEAVING_PYTHON

    isc_dsql_execute_immediate(
        con->status_vector,
        &con->db_handle,
        &unused_trans_handle,
        /* Cast is safe because sql_len has already been constrained: */
        (unsigned short) sql_len,
        sql,
        con->dialect,
        NULL
      );

    LEAVE_GCDL_WITHOUT_ENTERING_PYTHON
    LEAVE_GDAL_WITHOUT_ENTERING_PYTHON
    ENTER_GIL_WITHOUT_AFFECTING_DB

    /* For CREATE DATABASE statements, isc_dsql_execute_immediate is not
     * supposed to touch the transaction handle: */
    assert (unused_trans_handle == NULL_TRANS_HANDLE);
  }
  if (DB_API_ERROR(con->status_vector)) {
    raise_sql_exception(ProgrammingError, "pyob_create_database: ",
        con->status_vector
      );
    goto fail;
  }

  con->state = CON_STATE_OPEN;
  return (PyObject *) con;

  fail:
    assert (PyErr_Occurred());

    Py_XDECREF((PyObject *) con);

    return NULL;
} /* pyob_create_database */

static PyObject *pyob_Connection_drop_database(PyObject *self, PyObject *args) {
  CConnection *con;
  if (!PyArg_ParseTuple(args, "O!", &ConnectionType, &con) ) { goto fail; }

  CONN_REQUIRE_OPEN(con);
  /* CONN_REQUIRE_OPEN should enforce non-null db_handle, but assert anyway: */
  assert (con->db_handle != NULL_DB_HANDLE);

  /* Here, we first save the connection's db_handle, then ask Connection_close
   * to "close the connection, but don't actually detach."  This preserves the
   * uniformity of the cleanup code between the normal closure paths and
   * drop_database. */
  {
    isc_db_handle db_handle = con->db_handle;
    assert (con->state == CON_STATE_OPEN);
    assert (NOT_RUNNING_IN_CONNECTION_TIMEOUT_THREAD);
    if (Connection_close(con, TRUE, FALSE) != 0) {
      goto fail;
    }
    assert (con->state == CON_STATE_CLOSED);
    assert (con->db_handle == NULL_DB_HANDLE);
    /* We now restore the OPEN state and the db_handle to con; they'll be cleared
     * below, but only if the isc_drop_database call succeeds. */
    con->state = CON_STATE_OPEN;
    con->db_handle = db_handle;
  }

  LEAVE_GIL_WITHOUT_AFFECTING_DB
  ENTER_GDAL_WITHOUT_LEAVING_PYTHON
  ENTER_GCDL_WITHOUT_LEAVING_PYTHON

  isc_drop_database(con->status_vector, &con->db_handle);

  LEAVE_GCDL_WITHOUT_ENTERING_PYTHON
  LEAVE_GDAL_WITHOUT_ENTERING_PYTHON
  ENTER_GIL_WITHOUT_AFFECTING_DB

  if (DB_API_ERROR(con->status_vector)) {
    raise_sql_exception(OperationalError, "pyob_Connection_drop_database: ",
        con->status_vector
      );
    goto fail;
  }

  con->db_handle = NULL_DB_HANDLE;
  con->state = CON_STATE_CLOSED;

  RETURN_PY_NONE;

  fail:
    assert (PyErr_Occurred());
    return NULL;
} /* pyob_Connection_drop_database */