Skip to content

Commit 832ab10

Browse files
committed
api: native crud module support
Adds native api support for crud module [1] to use it from a connection object. 1. github.com/tarantool/crud Closes #205
1 parent 1154b3d commit 832ab10

14 files changed

+2729
-1
lines changed

Diff for: .github/workflows/packing.yml

+18
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ jobs:
9999
- name: Install test requirements
100100
run: pip3 install -r requirements-test.txt
101101

102+
- name: Install the crud module for testing purposes
103+
run: |
104+
curl -L https://tarantool.io/release/2/installer.sh | bash
105+
sudo apt install -y tt
106+
tt rocks install crud
107+
102108
- name: Run tests
103109
run: make test-pure-install
104110

@@ -331,6 +337,12 @@ jobs:
331337
- name: Install test requirements
332338
run: pip3 install -r requirements-test.txt
333339

340+
- name: Install the crud module for testing purposes
341+
run: |
342+
curl -L https://tarantool.io/release/2/installer.sh | bash
343+
sudo apt install -y tt
344+
tt rocks install crud
345+
334346
- name: Run tests
335347
run: make test-pure-install
336348

@@ -492,6 +504,12 @@ jobs:
492504
- name: Install test requirements
493505
run: pip3 install -r requirements-test.txt
494506

507+
- name: Install the crud module for testing purposes
508+
run: |
509+
curl -L https://tarantool.io/release/2/installer.sh | bash
510+
sudo apt install -y tt
511+
tt rocks install crud
512+
495513
- name: Run tests
496514
run: make test-pure-install
497515

Diff for: .github/workflows/reusable_testing.yml

+6
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,10 @@ jobs:
3939
- name: Install test requirements
4040
run: pip3 install -r requirements-test.txt
4141

42+
- name: Install the crud module for testing purposes
43+
run: |
44+
curl -L https://tarantool.io/release/2/installer.sh | bash
45+
sudo apt install -y tt
46+
tt rocks install crud
47+
4248
- run: make test

Diff for: .github/workflows/testing.yml

+21
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ jobs:
8585
- name: Install test requirements
8686
run: pip3 install -r requirements-test.txt
8787

88+
- name: Install the crud module for testing purposes
89+
run: |
90+
curl -L https://tarantool.io/release/2/installer.sh | bash
91+
sudo apt install -y tt
92+
tt rocks install crud
93+
8894
- name: Run tests
8995
run: make test
9096

@@ -143,6 +149,15 @@ jobs:
143149
- name: Install test requirements
144150
run: pip3 install -r requirements-test.txt
145151

152+
- name: Install the crud module for testing purposes
153+
# This is a workaround with TARANTOOL_DIR and should be reworked later.
154+
# See more here: https://github.com/tarantool/tt/issues/282
155+
run: |
156+
source tarantool-enterprise/env.sh
157+
curl -L https://tarantool.io/release/2/installer.sh | bash
158+
sudo apt install -y tt
159+
tt rocks install crud TARANTOOL_DIR=$PWD/tarantool-enterprise
160+
146161
- name: Run tests
147162
run: |
148163
source tarantool-enterprise/env.sh
@@ -196,6 +211,12 @@ jobs:
196211
- name: Install test requirements
197212
run: pip3 install -r requirements-test.txt
198213

214+
- name: Install the crud module for testing purposes
215+
run: |
216+
curl -L https://tarantool.io/release/2/installer.sh | bash
217+
sudo apt install -y tt
218+
tt rocks install crud
219+
199220
- name: Run tests
200221
run: make test-pure-install
201222

Diff for: CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Added
1010
- Support custom packer and unpacker factories (#191).
1111

12+
- Support [crud module](https://github.com/tarantool/crud) native API (#205).
13+
1214
### Changed
1315

1416
### Fixed

Diff for: docs/source/api/submodule-crud.rst

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module :py:mod:`tarantool.crud`
2+
================================
3+
4+
.. automodule:: tarantool.crud

Diff for: docs/source/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ API Reference
6363
api/module-tarantool.rst
6464
api/submodule-connection.rst
6565
api/submodule-connection-pool.rst
66+
api/submodule-crud.rst
6667
api/submodule-dbapi.rst
6768
api/submodule-error.rst
6869
api/submodule-mesh-connection.rst

Diff for: docs/source/quick-start.rst

+120
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,123 @@ with out-of-band message processing:
347347
348348
print(callback_res)
349349
>>> [[[100, 1]], [[200, 1]], [[300, 1]]]
350+
351+
352+
Interaction with the crud module
353+
----------------------------------
354+
355+
Through the :class:`~tarantool.Connection` object, you can access
356+
`crud module <https://github.com/tarantool/crud>`_ methods:
357+
358+
.. code-block:: python
359+
360+
>>> import tarantool
361+
>>> from tarantool.error import CrudModuleError, CrudModuleManyError, DatabaseError
362+
>>> conn = tarantool.Connection(host='localhost',port=3301)
363+
364+
>>> conn.crud_
365+
conn.crud_count( conn.crud_insert( conn.crud_insert_object_many(
366+
conn.crud_min( conn.crud_replace_object( conn.crud_stats(
367+
conn.crud_unflatten_rows( conn.crud_upsert_many( conn.crud_delete(
368+
conn.crud_insert_many( conn.crud_len( conn.crud_replace(
369+
conn.crud_replace_object_many( conn.crud_storage_info( conn.crud_update(
370+
conn.crud_upsert_object( conn.crud_get( conn.crud_insert_object(
371+
conn.crud_max( conn.crud_replace_many( conn.crud_select(
372+
conn.crud_truncate( conn.crud_upsert( conn.crud_upsert_object_many(
373+
374+
As an example, consider :meth:`~tarantool.Connection.crud_insert` and :meth:`~tarantool.Connection.crud_insert_object_many`.
375+
It is recommended to enclose calls in the try-except construction as follows:
376+
377+
.. code-block:: python
378+
379+
# Insert without exception:
380+
>>> res = conn.crud_insert('tester', (3500,300,'Rob'))
381+
>>> res
382+
<tarantool.crud.CrudResult object at 0x11a56e320>
383+
>>> res.
384+
res.metadata res.rows
385+
>>> res.rows
386+
[[3500, 300, 'Rob']]
387+
>>> res.metadata
388+
[{'name': 'id', 'type': 'unsigned'}, {'name': 'bucket_id', 'type': 'unsigned'}, {'name': 'name', 'type': 'string'}]
389+
390+
# Insert with exception (duplicate key exists):
391+
>>> try:
392+
... res = conn.crud_insert('tester', (3500,300,'Rob'))
393+
... except CrudModuleError as e:
394+
... exc_crud = e
395+
...
396+
>>> exc_crud
397+
CrudModuleError(0, 'Failed to insert: Duplicate key exists in unique index "primary_index" in space "tester" with old tuple - [3500, 300, "Rob"] and new tuple - [3500, 300, "Rob"]')
398+
>>> exc_crud.extra_info_error
399+
<tarantool.crud.CrudError object at 0x10a276950>
400+
>>> exc_crud.extra_info_error.
401+
exc_crud.extra_info_error.class_name exc_crud.extra_info_error.err exc_crud.extra_info_error.file exc_crud.extra_info_error.line exc_crud.extra_info_error.str
402+
>>> exc_crud.extra_info_error.class_name
403+
'InsertError'
404+
>>> exc_crud.extra_info_error.str
405+
'InsertError: Failed to insert: Duplicate key exists in unique index "primary_index" in space "tester" with old tuple - [3500, 300, "Rob"] and new tuple - [3500, 300, "Rob"]'
406+
407+
# In case of batch operation (*_many), CrudModuleManyError exception contains both result and errors (if there is a problem with at least one row).
408+
>>> try:
409+
... res = conn.crud_insert_object_many('tester', ({'id':3,'bucket_id':100,'name':'Ann'}, {'id':4,'bucket_id':100,'name':'Sam'}), {'timeout':100, 'rollback_on_error':False})
410+
... except CrudModuleManyError as e:
411+
... exc_crud = e
412+
...
413+
>>> exc_crud
414+
CrudModuleManyError(0, 'Got multiple errors, see errors_list')
415+
>>> exc_crud.success_list # some of the rows were inserted.
416+
<tarantool.crud.CrudResult object at 0x11a56f310>
417+
>>> exc_crud.success_list.rows
418+
[[1, 100, 'Bob'], [2, 100, 'Rob']]
419+
>>> exc_crud.errors_list # some of the rows were not inserted.
420+
[<tarantool.crud.CrudError object at 0x11a56e9e0>, <tarantool.crud.CrudError object at 0x11a56f490>]
421+
>>> exc_crud.errors_list[0].str
422+
'CallError: Failed for 037adb3a-b9e3-4f78-a6d1-9f0cdb6cbefc: Function returned an error: Duplicate key exists in unique index "primary_index" in space "tester" with old tuple - [3500, 300, "Rob"] and new tuple - [3500, 100, "Mike"]'
423+
>>> exc_crud.errors_list[1].str
424+
'InsertManyError: Failed to flatten object: FlattenError: Object is specified in bad format: FlattenError: Unknown field "second_name" is specified'
425+
426+
# If there are no problems with any rows, the entire response will be contained in the res variable.
427+
>>> res = conn.crud_insert_object_many('tester', ({'id':3,'bucket_id':100,'name':'Ann'}, {'id':4,'bucket_id':100,'name':'Sam'}), {'timeout':100, 'rollback_on_error':False})
428+
>>> res.rows
429+
[[3, 100, 'Ann'], [4, 100, 'Sam']]
430+
431+
If module crud not found on the router or user has not sufficient grants:
432+
433+
.. code-block:: python
434+
435+
>>> try:
436+
... res = conn.crud_insert('tester', (22221,300,'Rob'))
437+
... except DatabaseError as e:
438+
... exc_db = e
439+
...
440+
>>> exc_db
441+
DatabaseError(33, "Procedure 'crud.insert' is not defined. Ensure that you're calling crud.router and user has sufficient grants")
442+
>>> exc_db.extra_info
443+
BoxError(type='ClientError', file='/tmp/tarantool-20221003-6335-edruh3/tarantool-2.10.3/src/box/lua/call.c', line=112, message="Procedure 'crud.insert' is not defined", errno=0, errcode=33, fields=None, prev=None)
444+
445+
Using :meth:`~tarantool.Connection.crud_select` and :meth:`~tarantool.Connection.crud_unflatten_rows`:
446+
447+
.. code-block:: python
448+
449+
>>> res = conn.crud_select('tester', [], {'first':2})
450+
>>> res
451+
<tarantool.crud.CrudResult object at 0x10a276d10>
452+
>>> res.rows
453+
[[1, 100, 'Mike'], [2, 100, 'Bill']]
454+
>>> res.metadata
455+
[{'name': 'id', 'type': 'unsigned'}, {'name': 'bucket_id', 'type': 'unsigned'}, {'name': 'name', 'type': 'string'}]
456+
>>> r = conn.crud_unflatten_rows(res.rows, res.metadata)
457+
>>> r
458+
[{'id': 1, 'bucket_id': 100, 'name': 'Mike'}, {'id': 2, 'bucket_id': 100, 'name': 'Bill'}]
459+
460+
Using :meth:`~tarantool.Connection.crud_truncate` and :meth:`~tarantool.Connection.crud_len`:
461+
462+
.. code-block:: python
463+
464+
>>> res = conn.crud_len('tester')
465+
>>> res
466+
26
467+
>>> res = conn.crud_truncate('tester')
468+
>>> res
469+
True

0 commit comments

Comments
 (0)