示例#1
0
    def commit(self):
        self._check_thread()
        self._check_closed()
        if not self._in_transaction:
            return

        # PyPy fix for non-refcounting semantics: since 2.7.13 (and in
        # <= 2.6.x), the statements are not automatically reset upon
        # commit.  However, if this is followed by some specific SQL
        # operations like "drop table", these open statements come in
        # the way and cause the "drop table" to fail.  On CPython the
        # problem is much less important because typically all the old
        # statements are freed already by reference counting.  So here,
        # we copy all the still-alive statements to another list which
        # is usually ignored, except if we get SQLITE_LOCKED
        # afterwards---at which point we reset all statements in this
        # list.
        self.__statements_already_committed = self.__statements[:]

        statement_star = _ffi.new('sqlite3_stmt **')
        ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, statement_star,
                                      _ffi.NULL)
        try:
            if ret != _lib.SQLITE_OK:
                raise self._get_exception(ret)
            ret = _lib.sqlite3_step(statement_star[0])
            if ret != _lib.SQLITE_DONE:
                raise self._get_exception(ret)
            self._in_transaction = False
        finally:
            _lib.sqlite3_finalize(statement_star[0])
示例#2
0
 def _begin(self):
     statement_star = _ffi.new('sqlite3_stmt **')
     ret = _lib.sqlite3_prepare_v2(self._db, self._begin_statement, -1,
                                   statement_star, _ffi.NULL)
     try:
         if ret != _lib.SQLITE_OK:
             raise self._get_exception(ret)
         ret = _lib.sqlite3_step(statement_star[0])
         if ret != _lib.SQLITE_DONE:
             raise self._get_exception(ret)
     finally:
         _lib.sqlite3_finalize(statement_star[0])
示例#3
0
 def _begin(self):
     statement_star = _ffi.new("sqlite3_stmt **")
     ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, statement_star, _ffi.NULL)
     try:
         if ret != _lib.SQLITE_OK:
             raise self._get_exception(ret)
         ret = _lib.sqlite3_step(statement_star[0])
         if ret != _lib.SQLITE_DONE:
             raise self._get_exception(ret)
         self._in_transaction = True
     finally:
         _lib.sqlite3_finalize(statement_star[0])
示例#4
0
    def rollback(self):
        self._check_thread()
        self._check_closed()
        if not self.in_transaction:
            return

        self.__do_all_statements(Statement._reset, True)

        statement_star = _ffi.new('sqlite3_stmt **')
        ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1,
                                      statement_star, _ffi.NULL)
        try:
            if ret != _lib.SQLITE_OK:
                raise self._get_exception(ret)
            ret = _lib.sqlite3_step(statement_star[0])
            if ret != _lib.SQLITE_DONE:
                raise self._get_exception(ret)
        finally:
            _lib.sqlite3_finalize(statement_star[0])
示例#5
0
    def rollback(self):
        self._check_thread()
        self._check_closed()
        if not self._in_transaction:
            return

        self.__do_all_statements(Statement._reset, True)

        statement_star = _ffi.new("sqlite3_stmt **")
        ret = _lib.sqlite3_prepare_v2(self._db, b"ROLLBACK", -1, statement_star, _ffi.NULL)
        try:
            if ret != _lib.SQLITE_OK:
                raise self._get_exception(ret)
            ret = _lib.sqlite3_step(statement_star[0])
            if ret != _lib.SQLITE_DONE:
                raise self._get_exception(ret)
            self._in_transaction = False
        finally:
            _lib.sqlite3_finalize(statement_star[0])
示例#6
0
    def commit(self):
        self._check_thread()
        self._check_closed()
        if not self._in_transaction:
            return

        self.__do_all_statements(Statement._reset, False)

        statement_star = _ffi.new('sqlite3_stmt **')
        ret = _lib.sqlite3_prepare_v2(self._db, b"COMMIT", -1, statement_star,
                                      _ffi.NULL)
        try:
            if ret != _lib.SQLITE_OK:
                raise self._get_exception(ret)
            ret = _lib.sqlite3_step(statement_star[0])
            if ret != _lib.SQLITE_DONE:
                raise self._get_exception(ret)
            self._in_transaction = False
        finally:
            _lib.sqlite3_finalize(statement_star[0])
示例#7
0
    def executescript(self, sql):
        self.__check_cursor()
        self._reset = False
        if isinstance(sql, unicode):
            sql = sql.encode('utf-8')
        elif not isinstance(sql, str):
            raise ValueError("script argument must be unicode or string.")
        statement_star = _ffi.new('sqlite3_stmt **')
        next_char = _ffi.new('char **')

        self.__connection.commit()
        while True:
            c_sql = _ffi.new("char[]", sql)
            rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1,
                                      statement_star, next_char)
            if rc != _lib.SQLITE_OK:
                raise self.__connection._get_exception(rc)

            rc = _lib.SQLITE_ROW
            while rc == _lib.SQLITE_ROW:
                if not statement_star[0]:
                    rc = _lib.SQLITE_OK
                else:
                    rc = _lib.sqlite3_step(statement_star[0])

            if rc != _lib.SQLITE_DONE:
                _lib.sqlite3_finalize(statement_star[0])
                if rc == _lib.SQLITE_OK:
                    break
                else:
                    raise self.__connection._get_exception(rc)

            rc = _lib.sqlite3_finalize(statement_star[0])
            if rc != _lib.SQLITE_OK:
                raise self.__connection._get_exception(rc)

            sql = _ffi.string(next_char[0])
            if not sql:
                break
        return self
示例#8
0
    def executescript(self, sql):
        self.__check_cursor()
        self._reset = False
        if isinstance(sql, unicode):
            sql = sql.encode('utf-8')
        elif not isinstance(sql, str):
            raise ValueError("script argument must be unicode or string.")
        statement_star = _ffi.new('sqlite3_stmt **')
        next_char = _ffi.new('char **')

        self.__connection.commit()
        while True:
            c_sql = _ffi.new("char[]", sql)
            rc = _lib.sqlite3_prepare(self.__connection._db, c_sql, -1,
                                      statement_star, next_char)
            if rc != _lib.SQLITE_OK:
                raise self.__connection._get_exception(rc)

            rc = _lib.SQLITE_ROW
            while rc == _lib.SQLITE_ROW:
                if not statement_star[0]:
                    rc = _lib.SQLITE_OK
                else:
                    rc = _lib.sqlite3_step(statement_star[0])

            if rc != _lib.SQLITE_DONE:
                _lib.sqlite3_finalize(statement_star[0])
                if rc == _lib.SQLITE_OK:
                    break
                else:
                    raise self.__connection._get_exception(rc)

            rc = _lib.sqlite3_finalize(statement_star[0])
            if rc != _lib.SQLITE_OK:
                raise self.__connection._get_exception(rc)

            sql = _ffi.string(next_char[0])
            if not sql:
                break
        return self
示例#9
0
    def __next__(self):
        self.__check_cursor()
        self.__check_reset()
        if not self.__statement:
            raise StopIteration

        try:
            next_row = self.__next_row
        except AttributeError:
            raise StopIteration
        del self.__next_row

        if self.row_factory is not None:
            next_row = self.row_factory(self, next_row)

        ret = _lib.sqlite3_step(self.__statement._statement)
        if ret == _lib.SQLITE_ROW:
            self.__next_row = self.__fetch_one_row()
        else:
            self.__statement._reset()
            if ret != _lib.SQLITE_DONE:
                raise self.__connection._get_exception(ret)
        return next_row
示例#10
0
    def __next__(self):
        self.__check_cursor()
        self.__check_reset()
        if not self.__statement:
            raise StopIteration

        try:
            next_row = self.__next_row
        except AttributeError:
            raise StopIteration
        del self.__next_row

        if self.row_factory is not None:
            next_row = self.row_factory(self, next_row)

        ret = _lib.sqlite3_step(self.__statement._statement)
        if ret == _lib.SQLITE_ROW:
            self.__next_row = self.__fetch_one_row()
        else:
            self.__statement._reset()
            if ret != _lib.SQLITE_DONE:
                raise self.__connection._get_exception(ret)
        return next_row
示例#11
0
    def __execute(self, multiple, sql, many_params):
        self.__locked = True
        self._reset = False
        try:
            del self.__next_row
        except AttributeError:
            pass
        try:
            if not isinstance(sql, basestring):
                raise ValueError("operation parameter must be str or unicode")
            try:
                del self.__description
            except AttributeError:
                pass
            self.__rowcount = -1
            self.__statement = self.__connection._statement_cache.get(sql)

            if self.__connection._isolation_level is not None:
                if self.__statement._type in (_STMT_TYPE_UPDATE,
                                              _STMT_TYPE_DELETE,
                                              _STMT_TYPE_INSERT,
                                              _STMT_TYPE_REPLACE):
                    if not self.__connection._in_transaction:
                        self.__connection._begin()
                elif self.__statement._type == _STMT_TYPE_OTHER:
                    if self.__connection._in_transaction:
                        self.__connection.commit()
                elif self.__statement._type == _STMT_TYPE_SELECT:
                    if multiple:
                        raise ProgrammingError("You cannot execute SELECT "
                                               "statements in executemany().")

            for params in many_params:
                self.__statement._set_params(params)

                # Actually execute the SQL statement

                ret = _lib.sqlite3_step(self.__statement._statement)

                # PyPy: if we get SQLITE_LOCKED, it's probably because
                # one of the cursors created previously is still alive
                # and not reset and the operation we're trying to do
                # makes Sqlite unhappy about that.  In that case, we
                # automatically reset all old cursors and try again.
                if ret == _lib.SQLITE_LOCKED:
                    self.__connection._reset_already_committed_statements()
                    ret = _lib.sqlite3_step(self.__statement._statement)

                if ret == _lib.SQLITE_ROW:
                    if multiple:
                        raise ProgrammingError(
                            "executemany() can only execute DML statements.")
                    self.__build_row_cast_map()
                    self.__next_row = self.__fetch_one_row()
                elif ret == _lib.SQLITE_DONE:
                    if not multiple:
                        self.__statement._reset()
                else:
                    self.__statement._reset()
                    raise self.__connection._get_exception(ret)

                if self.__statement._type in (_STMT_TYPE_UPDATE,
                                              _STMT_TYPE_DELETE,
                                              _STMT_TYPE_INSERT,
                                              _STMT_TYPE_REPLACE):
                    if self.__rowcount == -1:
                        self.__rowcount = 0
                    self.__rowcount += _lib.sqlite3_changes(
                        self.__connection._db)

                if not multiple and self.__statement._type == _STMT_TYPE_INSERT:
                    self.__lastrowid = _lib.sqlite3_last_insert_rowid(
                        self.__connection._db)
                else:
                    self.__lastrowid = None

                if multiple:
                    self.__statement._reset()
        finally:
            self.__connection._in_transaction = \
                not _lib.sqlite3_get_autocommit(self.__connection._db)
            self.__locked = False
        return self
示例#12
0
    def __execute(self, multiple, sql, many_params):
        self.__locked = True
        self._reset = False
        try:
            del self.__next_row
        except AttributeError:
            pass
        try:
            if not isinstance(sql, basestring):
                raise ValueError("operation parameter must be str or unicode")
            try:
                del self.__description
            except AttributeError:
                pass
            self.__rowcount = -1
            self.__statement = self.__connection._statement_cache.get(sql)

            if self.__connection._isolation_level is not None:
                if self.__statement._type in (_STMT_TYPE_UPDATE,
                                              _STMT_TYPE_DELETE,
                                              _STMT_TYPE_INSERT,
                                              _STMT_TYPE_REPLACE):
                    if not self.__connection._in_transaction:
                        self.__connection._begin()
                elif self.__statement._type == _STMT_TYPE_OTHER:
                    if self.__connection._in_transaction:
                        self.__connection.commit()
                elif self.__statement._type == _STMT_TYPE_SELECT:
                    if multiple:
                        raise ProgrammingError("You cannot execute SELECT "
                                               "statements in executemany().")

            for params in many_params:
                self.__statement._set_params(params)

                # Actually execute the SQL statement
                ret = _lib.sqlite3_step(self.__statement._statement)

                if ret == _lib.SQLITE_ROW:
                    if multiple:
                        raise ProgrammingError(
                            "executemany() can only execute DML statements.")
                    self.__build_row_cast_map()
                    self.__next_row = self.__fetch_one_row()
                elif ret == _lib.SQLITE_DONE:
                    if not multiple:
                        self.__statement._reset()
                else:
                    self.__statement._reset()
                    raise self.__connection._get_exception(ret)

                if self.__statement._type in (_STMT_TYPE_UPDATE,
                                              _STMT_TYPE_DELETE,
                                              _STMT_TYPE_INSERT,
                                              _STMT_TYPE_REPLACE):
                    if self.__rowcount == -1:
                        self.__rowcount = 0
                    self.__rowcount += _lib.sqlite3_changes(
                        self.__connection._db)

                if not multiple and self.__statement._type == _STMT_TYPE_INSERT:
                    self.__lastrowid = _lib.sqlite3_last_insert_rowid(
                        self.__connection._db)
                else:
                    self.__lastrowid = None

                if multiple:
                    self.__statement._reset()
        finally:
            self.__connection._in_transaction = \
                not _lib.sqlite3_get_autocommit(self.__connection._db)
            self.__locked = False
        return self
示例#13
0
    def __execute(self, multiple, sql, many_params):
        self.__locked = True
        self._reset = False
        try:
            del self.__next_row
        except AttributeError:
            pass
        try:
            if not isinstance(sql, basestring):
                raise ValueError("operation parameter must be str or unicode")
            try:
                del self.__description
            except AttributeError:
                pass
            self.__rowcount = -1
            self.__statement = self.__connection._statement_cache.get(sql)

            if self.__connection._isolation_level is not None:
                if self.__statement._type in (
                    _STMT_TYPE_UPDATE,
                    _STMT_TYPE_DELETE,
                    _STMT_TYPE_INSERT,
                    _STMT_TYPE_REPLACE
                ):
                    if not self.__connection._in_transaction:
                        self.__connection._begin()
                elif self.__statement._type == _STMT_TYPE_OTHER:
                    if self.__connection._in_transaction:
                        self.__connection.commit()
                elif self.__statement._type == _STMT_TYPE_SELECT:
                    if multiple:
                        raise ProgrammingError("You cannot execute SELECT "
                                               "statements in executemany().")

            for params in many_params:
                self.__statement._set_params(params)

                # Actually execute the SQL statement
                ret = _lib.sqlite3_step(self.__statement._statement)

                if ret == _lib.SQLITE_ROW:
                    if multiple:
                        raise ProgrammingError("executemany() can only execute DML statements.")
                    self.__build_row_cast_map()
                    self.__next_row = self.__fetch_one_row()
                elif ret == _lib.SQLITE_DONE:
                    if not multiple:
                        self.__statement._reset()
                else:
                    self.__statement._reset()
                    raise self.__connection._get_exception(ret)

                if self.__statement._type in (
                    _STMT_TYPE_UPDATE,
                    _STMT_TYPE_DELETE,
                    _STMT_TYPE_INSERT,
                    _STMT_TYPE_REPLACE
                ):
                    if self.__rowcount == -1:
                        self.__rowcount = 0
                    self.__rowcount += _lib.sqlite3_changes(self.__connection._db)

                if not multiple and self.__statement._type == _STMT_TYPE_INSERT:
                    self.__lastrowid = _lib.sqlite3_last_insert_rowid(self.__connection._db)
                else:
                    self.__lastrowid = None

                if multiple:
                    self.__statement._reset()
        finally:
            self.__connection._in_transaction = \
                not _lib.sqlite3_get_autocommit(self.__connection._db)
            self.__locked = False
        return self