summaryrefslogtreecommitdiffstats
path: root/Modules/_sqlite/clinic
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2022-04-15 00:02:56 (GMT)
committerGitHub <noreply@github.com>2022-04-15 00:02:56 (GMT)
commitee475430d431814cbb6eb5e8a6c0ae51943349d4 (patch)
treee9464bb51a6304a77da9461d28564b00689edfc1 /Modules/_sqlite/clinic
parentc9d41bcd68dbe339396523e931904930a87819b9 (diff)
downloadcpython-ee475430d431814cbb6eb5e8a6c0ae51943349d4.zip
cpython-ee475430d431814cbb6eb5e8a6c0ae51943349d4.tar.gz
cpython-ee475430d431814cbb6eb5e8a6c0ae51943349d4.tar.bz2
gh-69093: Support basic incremental I/O to blobs in `sqlite3` (GH-30680)
Authored-by: Aviv Palivoda <palaviv@gmail.com> Co-authored-by: Erlend E. Aasland <erlend.aasland@innova.no> Co-authored-by: palaviv <palaviv@gmail.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Diffstat (limited to 'Modules/_sqlite/clinic')
-rw-r--r--Modules/_sqlite/clinic/blob.c.h165
-rw-r--r--Modules/_sqlite/clinic/connection.c.h106
2 files changed, 270 insertions, 1 deletions
diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h
new file mode 100644
index 0000000..30b3e3c
--- /dev/null
+++ b/Modules/_sqlite/clinic/blob.c.h
@@ -0,0 +1,165 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(blob_close__doc__,
+"close($self, /)\n"
+"--\n"
+"\n"
+"Close the blob.");
+
+#define BLOB_CLOSE_METHODDEF \
+ {"close", (PyCFunction)blob_close, METH_NOARGS, blob_close__doc__},
+
+static PyObject *
+blob_close_impl(pysqlite_Blob *self);
+
+static PyObject *
+blob_close(pysqlite_Blob *self, PyObject *Py_UNUSED(ignored))
+{
+ return blob_close_impl(self);
+}
+
+PyDoc_STRVAR(blob_read__doc__,
+"read($self, length=-1, /)\n"
+"--\n"
+"\n"
+"Read data at the current offset position.\n"
+"\n"
+" length\n"
+" Read length in bytes.\n"
+"\n"
+"If the end of the blob is reached, the data up to end of file will be returned.\n"
+"When length is not specified, or is negative, Blob.read() will read until the\n"
+"end of the blob.");
+
+#define BLOB_READ_METHODDEF \
+ {"read", (PyCFunction)(void(*)(void))blob_read, METH_FASTCALL, blob_read__doc__},
+
+static PyObject *
+blob_read_impl(pysqlite_Blob *self, int length);
+
+static PyObject *
+blob_read(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ int length = -1;
+
+ if (!_PyArg_CheckPositional("read", nargs, 0, 1)) {
+ goto exit;
+ }
+ if (nargs < 1) {
+ goto skip_optional;
+ }
+ length = _PyLong_AsInt(args[0]);
+ if (length == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional:
+ return_value = blob_read_impl(self, length);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(blob_write__doc__,
+"write($self, data, /)\n"
+"--\n"
+"\n"
+"Write data at the current offset.\n"
+"\n"
+"This function cannot change the blob length. Writing beyond the end of the\n"
+"blob will result in an exception being raised.");
+
+#define BLOB_WRITE_METHODDEF \
+ {"write", (PyCFunction)blob_write, METH_O, blob_write__doc__},
+
+static PyObject *
+blob_write_impl(pysqlite_Blob *self, Py_buffer *data);
+
+static PyObject *
+blob_write(pysqlite_Blob *self, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ Py_buffer data = {NULL, NULL};
+
+ if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
+ goto exit;
+ }
+ if (!PyBuffer_IsContiguous(&data, 'C')) {
+ _PyArg_BadArgument("write", "argument", "contiguous buffer", arg);
+ goto exit;
+ }
+ return_value = blob_write_impl(self, &data);
+
+exit:
+ /* Cleanup for data */
+ if (data.obj) {
+ PyBuffer_Release(&data);
+ }
+
+ return return_value;
+}
+
+PyDoc_STRVAR(blob_seek__doc__,
+"seek($self, offset, origin=0, /)\n"
+"--\n"
+"\n"
+"Set the current access position to offset.\n"
+"\n"
+"The origin argument defaults to os.SEEK_SET (absolute blob positioning).\n"
+"Other values for origin are os.SEEK_CUR (seek relative to the current position)\n"
+"and os.SEEK_END (seek relative to the blob\'s end).");
+
+#define BLOB_SEEK_METHODDEF \
+ {"seek", (PyCFunction)(void(*)(void))blob_seek, METH_FASTCALL, blob_seek__doc__},
+
+static PyObject *
+blob_seek_impl(pysqlite_Blob *self, int offset, int origin);
+
+static PyObject *
+blob_seek(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ int offset;
+ int origin = 0;
+
+ if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) {
+ goto exit;
+ }
+ offset = _PyLong_AsInt(args[0]);
+ if (offset == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+ if (nargs < 2) {
+ goto skip_optional;
+ }
+ origin = _PyLong_AsInt(args[1]);
+ if (origin == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional:
+ return_value = blob_seek_impl(self, offset, origin);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(blob_tell__doc__,
+"tell($self, /)\n"
+"--\n"
+"\n"
+"Return the current access position for the blob.");
+
+#define BLOB_TELL_METHODDEF \
+ {"tell", (PyCFunction)blob_tell, METH_NOARGS, blob_tell__doc__},
+
+static PyObject *
+blob_tell_impl(pysqlite_Blob *self);
+
+static PyObject *
+blob_tell(pysqlite_Blob *self, PyObject *Py_UNUSED(ignored))
+{
+ return blob_tell_impl(self);
+}
+/*[clinic end generated code: output=d3a02b127f2cfa58 input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h
index 2b933f8..d459708 100644
--- a/Modules/_sqlite/clinic/connection.c.h
+++ b/Modules/_sqlite/clinic/connection.c.h
@@ -145,6 +145,110 @@ exit:
return return_value;
}
+PyDoc_STRVAR(blobopen__doc__,
+"blobopen($self, table, column, row, /, *, readonly=False, name=\'main\')\n"
+"--\n"
+"\n"
+"Open and return a BLOB object.\n"
+"\n"
+" table\n"
+" Table name.\n"
+" column\n"
+" Column name.\n"
+" row\n"
+" Row index.\n"
+" readonly\n"
+" Open the BLOB without write permissions.\n"
+" name\n"
+" Database name.");
+
+#define BLOBOPEN_METHODDEF \
+ {"blobopen", (PyCFunction)(void(*)(void))blobopen, METH_FASTCALL|METH_KEYWORDS, blobopen__doc__},
+
+static PyObject *
+blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
+ int row, int readonly, const char *name);
+
+static PyObject *
+blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"", "", "", "readonly", "name", NULL};
+ static _PyArg_Parser _parser = {NULL, _keywords, "blobopen", 0};
+ PyObject *argsbuf[5];
+ Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
+ const char *table;
+ const char *col;
+ int row;
+ int readonly = 0;
+ const char *name = "main";
+
+ args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf);
+ if (!args) {
+ goto exit;
+ }
+ if (!PyUnicode_Check(args[0])) {
+ _PyArg_BadArgument("blobopen", "argument 1", "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("blobopen", "argument 2", "str", args[1]);
+ goto exit;
+ }
+ Py_ssize_t col_length;
+ col = PyUnicode_AsUTF8AndSize(args[1], &col_length);
+ if (col == NULL) {
+ goto exit;
+ }
+ if (strlen(col) != (size_t)col_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("blobopen", "argument 'name'", "str", args[4]);
+ goto exit;
+ }
+ Py_ssize_t name_length;
+ name = PyUnicode_AsUTF8AndSize(args[4], &name_length);
+ if (name == NULL) {
+ goto exit;
+ }
+ if (strlen(name) != (size_t)name_length) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
+ goto exit;
+ }
+skip_optional_kwonly:
+ return_value = blobopen_impl(self, table, col, row, readonly, name);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(pysqlite_connection_close__doc__,
"close($self, /)\n"
"--\n"
@@ -1041,4 +1145,4 @@ exit:
#ifndef DESERIALIZE_METHODDEF
#define DESERIALIZE_METHODDEF
#endif /* !defined(DESERIALIZE_METHODDEF) */
-/*[clinic end generated code: output=b9af1b52fda808bf input=a9049054013a1b77]*/
+/*[clinic end generated code: output=be2f526e78fa65b1 input=a9049054013a1b77]*/