Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
4fa0e91
support BLOB incremental I/O in sqlite module
palaviv Feb 24, 2017
3fe9108
Note that blob size cannot be changed using the blob object
palaviv Feb 25, 2017
865c1c8
Use assertRaises in tests
palaviv Feb 25, 2017
788fd54
Fix doc error
palaviv Feb 25, 2017
a1361e5
blob support sequence protocol
palaviv Mar 4, 2017
5aedfba
Calculate blob length once at creation
palaviv Mar 4, 2017
db6ef32
Add initial Doc for sequence protocol
palaviv Mar 4, 2017
219f4cb
Don't support blob operation
palaviv Apr 18, 2018
6dafe0e
move news entry to blurb
palaviv Apr 18, 2018
ffac901
Add blob to PCBuild
palaviv Apr 18, 2018
3475fa1
Update version
palaviv May 8, 2019
f6015ff
Fix memory leak
palaviv May 8, 2019
01e526c
Update version
palaviv Jul 29, 2020
354bebf
Fix CR comments in documentation and testing
palaviv Aug 3, 2020
9709456
Fix CR comments in code
palaviv Aug 3, 2020
e6e5099
Make readonly and dbname keyword arguements only
palaviv Aug 3, 2020
e9a8080
Fix more CR comments
palaviv Aug 3, 2020
d4fb1b5
Add more indicative error on write bigger then blob length
palaviv Aug 3, 2020
a7288f9
Merge branch 'main' into sqlite-blob
Sep 10, 2021
525a9c3
Adapt sqlite3.Connection.open_blob() to AC
Sep 10, 2021
2f65cc8
Adapt sqlite.Blob to AC
Sep 10, 2021
0dd047f
PEP 7 and normalised naming
Sep 10, 2021
d34a77b
Use Py_NewRef and Py_IsNone
Sep 10, 2021
9d55705
Harden blob_open()
Sep 10, 2021
d47ea17
Move blob init to blob_open()
Sep 10, 2021
e07a116
initialise rc in blob_ass_subscript()
Sep 10, 2021
982c812
Improve blob.seek() parameter naming
Sep 10, 2021
e92495b
Adapt to heap types and allow calling close multiple times
Sep 10, 2021
8f2ce8a
Consolidate tests
Sep 10, 2021
0a87520
Naming: read_length => length
Sep 10, 2021
32132cf
Wrap error handling in support function
Sep 10, 2021
287803e
Add blob seek position markers as constants
Sep 10, 2021
0fc5a39
Adjust SQLITE_ABORT error message
Sep 10, 2021
cd0bde1
Remove unneeded sqlite3_blob_close() and fix GC tracking
Sep 10, 2021
cf7e15e
Use close_blob() in pysqlite_close_all_blobs()
Sep 10, 2021
7e77217
Refactor write/read
Sep 10, 2021
c57e45a
Sipmlify __exit__
Sep 10, 2021
dd76f72
Use new slice API
Sep 10, 2021
237684e
Refactor very large functions
Sep 11, 2021
58905e8
Simplify subscript slice
Sep 11, 2021
9d69fca
Consolidate more tests
Sep 11, 2021
285bb3d
Use supplied offset in inner_read()
Sep 11, 2021
2f3051a
Simplify test
Sep 11, 2021
fd7c311
Simplify assign subscript slice
Sep 11, 2021
0644e87
Early error checking, and use PyBytes_AS_STRING() when possible
Sep 11, 2021
ced431a
Expand test suite
Sep 11, 2021
2dae1b9
Remove unneeded parts of sequence protocol
Sep 11, 2021
e8fa47e
Normalise error messages
Sep 11, 2021
6441668
Improve error message/type for to large subscript assignment
Sep 11, 2021
03d2152
Normalise naming: write_inner => inner_write
Sep 11, 2021
9360e62
Adjust comment
Sep 11, 2021
8eb16f7
Move blob_seterror() closer to where it's first used
Sep 11, 2021
411d07e
Fetch state from connection in check_blob()
Sep 11, 2021
8149e36
Remove unused declaration
Sep 11, 2021
56b4caa
Doc adjustments
Sep 11, 2021
afdeb2e
Add What's New and adjust NEWS
Sep 11, 2021
b12219f
Use sqlite3_blob_bytes() iso. storing length on blob object
Sep 12, 2021
32a21d8
Merge branch 'main' into sqlite-blob
Sep 12, 2021
36b0ca1
Also remove length from blob_open()
Sep 12, 2021
3d91705
Add get subscript index helper
Sep 12, 2021
ceee315
Expand test suite
Sep 12, 2021
44f4cd3
Merge branch 'main' into sqlite-blob
Sep 21, 2021
220b576
Merge branch 'main' into sqlite-blob
Nov 17, 2021
d9b5cdf
Format docs with linewidth 80
Nov 17, 2021
aaa2721
Improve tests
Nov 17, 2021
18e5118
Merge branch 'main' into sqlite-blob
Jan 2, 2022
8f685ba
Add clinic_state() stub. (Currently not used)
Jan 2, 2022
96df661
Visit/clear blob type during module traverse/clear
Jan 2, 2022
97d12a8
Harden some tests, simplify others
Jan 2, 2022
2e63b3e
Simplify example
Jan 3, 2022
be27747
Update docs
Jan 3, 2022
5add365
Simplify tests
Jan 3, 2022
bacf087
Safe close
Jan 3, 2022
5ff202d
Condense a comment
Jan 3, 2022
1fa5901
Make sure we catch int overflow for all types of writes
Jan 3, 2022
16f4d0d
Merge branch 'main' into sqlite-blob-all
Jan 18, 2022
7aec288
Fix typo in test name
Jan 18, 2022
aaaf7ab
Improve test
Jan 18, 2022
f9e65c0
Improve tests
Jan 18, 2022
6a5c864
Always check length in inner write
Jan 18, 2022
ea1045c
Fix missing array sentinel
Jan 18, 2022
2f848d9
Match apsw's API open_blob => blobopen
Jan 19, 2022
8d906bc
Fix overflow test on win x64
Jan 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adapt sqlite3.Connection.open_blob() to AC
  • Loading branch information
Erlend E. Aasland committed Sep 10, 2021
commit 525a9c3e6c7418309054e812fd7fd2bbf358a981
97 changes: 96 additions & 1 deletion Modules/_sqlite/clinic/connection.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,101 @@ pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_
return return_value;
}

PyDoc_STRVAR(pysqlite_connection_open_blob__doc__,
"open_blob($self, /, table, column, row, *, readonly=False,\n"
" dbname=\'main\')\n"
"--\n"
"\n"
"Return a blob object. Non-standard.");

#define PYSQLITE_CONNECTION_OPEN_BLOB_METHODDEF \
{"open_blob", (PyCFunction)(void(*)(void))pysqlite_connection_open_blob, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_open_blob__doc__},

static PyObject *
pysqlite_connection_open_blob_impl(pysqlite_Connection *self,
const char *table, const char *column,
int row, int readonly, const char *dbname);

static PyObject *
pysqlite_connection_open_blob(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
static const char * const _keywords[] = {"table", "column", "row", "readonly", "dbname", NULL};
static _PyArg_Parser _parser = {NULL, _keywords, "open_blob", 0};
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
const char *table;
const char *column;
int row;
int readonly = 0;
const char *dbname = "main";

args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf);
if (!args) {
goto exit;
}
if (!PyUnicode_Check(args[0])) {
_PyArg_BadArgument("open_blob", "argument 'table'", "str", args[0]);
goto exit;
}
Py_ssize_t table_length;
table = PyUnicode_AsUTF8AndSize(args[0], &table_length);
if (table == NULL) {
goto exit;
}
if (strlen(table) != (size_t)table_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
if (!PyUnicode_Check(args[1])) {
_PyArg_BadArgument("open_blob", "argument 'column'", "str", args[1]);
goto exit;
}
Py_ssize_t column_length;
column = PyUnicode_AsUTF8AndSize(args[1], &column_length);
if (column == NULL) {
goto exit;
}
if (strlen(column) != (size_t)column_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
row = _PyLong_AsInt(args[2]);
if (row == -1 && PyErr_Occurred()) {
goto exit;
}
if (!noptargs) {
goto skip_optional_kwonly;
}
if (args[3]) {
readonly = _PyLong_AsInt(args[3]);
if (readonly == -1 && PyErr_Occurred()) {
goto exit;
}
if (!--noptargs) {
goto skip_optional_kwonly;
}
}
if (!PyUnicode_Check(args[4])) {
_PyArg_BadArgument("open_blob", "argument 'dbname'", "str", args[4]);
goto exit;
}
Py_ssize_t dbname_length;
dbname = PyUnicode_AsUTF8AndSize(args[4], &dbname_length);
if (dbname == NULL) {
goto exit;
}
if (strlen(dbname) != (size_t)dbname_length) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
goto exit;
}
skip_optional_kwonly:
return_value = pysqlite_connection_open_blob_impl(self, table, column, row, readonly, dbname);

exit:
return return_value;
}

PyDoc_STRVAR(pysqlite_connection_close__doc__,
"close($self, /)\n"
"--\n"
Expand Down Expand Up @@ -816,4 +911,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss
#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
#endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */
/*[clinic end generated code: output=9c0dfc6c1ebf9039 input=a9049054013a1b77]*/
/*[clinic end generated code: output=2c37726d47594c3d input=a9049054013a1b77]*/
35 changes: 19 additions & 16 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,26 +374,30 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory)
return cursor;
}

PyObject* pysqlite_connection_blob(pysqlite_Connection *self, PyObject *args,
PyObject *kwargs)
/*[clinic input]
_sqlite3.Connection.open_blob as pysqlite_connection_open_blob

table: str
column: str
row: int
*
readonly: bool(accept={int}) = False
dbname: str = "main"

Return a blob object. Non-standard.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_open_blob_impl(pysqlite_Connection *self,
const char *table, const char *column,
int row, int readonly, const char *dbname)
/*[clinic end generated code: output=54dfadc6f1283245 input=38c93f0f7d73a1ef]*/
{
static char *kwlist[] = {"table", "column", "row", "readonly",
"dbname", NULL};
int rc;
const char *dbname = "main", *table, *column;
long long row;
int readonly = 0;
sqlite3_blob *blob;
pysqlite_Blob *pyblob = NULL;
PyObject *weakref;


if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssL|$ps", kwlist,
&table, &column, &row, &readonly,
&dbname)) {
return NULL;
}

Py_BEGIN_ALLOW_THREADS
rc = sqlite3_blob_open(self->db, dbname, table, column, row,
!readonly, &blob);
Expand Down Expand Up @@ -1957,8 +1961,6 @@ static PyGetSetDef connection_getset[] = {
};

static PyMethodDef connection_methods[] = {
{"open_blob", (PyCFunction)pysqlite_connection_blob, METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("return a blob object")},
PYSQLITE_CONNECTION_BACKUP_METHODDEF
PYSQLITE_CONNECTION_CLOSE_METHODDEF
PYSQLITE_CONNECTION_COMMIT_METHODDEF
Expand All @@ -1975,6 +1977,7 @@ static PyMethodDef connection_methods[] = {
PYSQLITE_CONNECTION_INTERRUPT_METHODDEF
PYSQLITE_CONNECTION_ITERDUMP_METHODDEF
PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
PYSQLITE_CONNECTION_OPEN_BLOB_METHODDEF
PYSQLITE_CONNECTION_ROLLBACK_METHODDEF
PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF
PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF
Expand Down