Skip to content

Commit cc60ec6

Browse files
author
Abhishek Singh
committed
v1.0.0 changes
1. Include lastrowdid in the response if available 2. Include rowcount in the response if available 3. Changed the key `row_count` -> `rowcount` to be inline with SQLite terminology 4. Removed unncessary list comprehension when generating a resultset.Now, we simply use `list` 5. Minor code formatting changes for better readability
1 parent 2968a65 commit cc60ec6

10 files changed

Lines changed: 124 additions & 40 deletions

File tree

.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ docker_examples
1111
.coverage
1212
.pytest_cache
1313
.coverage
14+
sqlite_demo.py
15+
example.db
16+
venv/

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ build/
77
dist/
88
.coverage
99
.pytest_cache
10-
.coverage
10+
.coverage
11+
sqlite_demo.py
12+
example.db
13+
venv/

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ matrix:
88
- os: linux
99
python: 3.8
1010
- os: linux
11-
python: pypy3
11+
python: 3.9
12+
- os: linux
13+
python: pypy3.6-7.1.1
1214
install:
1315
- pip install --upgrade pip
1416
- pip install pytest coverage coveralls

README.md

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
# sqlite_rx [![Travis](https://travis-ci.org/aosingh/sqlite_rx.svg?branch=master)](https://travis-ci.org/aosingh/sqlite_rx) [![PyPI version](https://badge.fury.io/py/sqlite-rx.svg)](https://pypi.python.org/pypi/sqlite-rx) [![Coverage Status](https://coveralls.io/repos/github/aosingh/sqlite_rx/badge.svg?branch=master)](https://coveralls.io/github/aosingh/sqlite_rx?branch=master)
1+
# sqlite_rx [![Downloads](https://pepy.tech/badge/sqlite-rx)](https://pepy.tech/project/sqlite-rx) [![Travis](https://travis-ci.org/aosingh/sqlite_rx.svg?branch=master)](https://travis-ci.org/aosingh/sqlite_rx) [![PyPI version](https://badge.fury.io/py/sqlite-rx.svg)](https://pypi.python.org/pypi/sqlite-rx) [![Coverage Status](https://coveralls.io/repos/github/aosingh/sqlite_rx/badge.svg?branch=master)](https://coveralls.io/github/aosingh/sqlite_rx?branch=master)
22
[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)]((https://www.python.org/downloads/release/python-370/)) [![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/) [![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-380/)
3+
[![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)]((https://www.python.org/downloads/release/python-390/))
34
[![PyPy3](https://img.shields.io/badge/python-PyPy3-blue.svg)](https://www.pypy.org/index.html)
45
## Background
56

67
[SQLite](https://www.sqlite.org/index.html) is a lightweight database written in C.
78
The Python programming language has in-built support to interact with the database(locally) which is either stored on disk or in memory.
89

9-
## Introducing sqlite_rx (SQLite remote execution)
10+
## Introducing sqlite_rx - SQLite remote query execution
1011
With `sqlite_rx`, clients should be able to communicate with an `SQLiteServer` in a fast, simple and secure manner and execute queries remotely.
1112

1213
Key Features
@@ -98,20 +99,6 @@ logging.config.dictConfig(get_default_logger_settings(logging.DEBUG))
9899
client = SQLiteClient(connect_address="tcp://127.0.0.1:5000")
99100
```
100101

101-
### SELECT statement: (Table not present)
102-
```python
103-
from pprint import pprint
104-
result = client.execute("SELECT * FROM IDOLS")
105-
pprint(result)
106-
107-
```
108-
OUTPUT
109-
```text
110-
{'error': {'message': 'sqlite3.OperationalError: no such table: IDOLS',
111-
'type': 'sqlite3.OperationalError'},
112-
'items': []}
113-
```
114-
115102
### CREATE TABLE statement
116103

117104
```python
@@ -164,7 +151,7 @@ pprint(result)
164151
OUTPUT
165152

166153
```text
167-
{'error': None, 'items': [], 'row_count': 27}
154+
{'error': None, 'items': [], 'rowcount': 27}
168155
```
169156

170157
### SELECT with WHERE clause
@@ -188,7 +175,7 @@ OUTPUT
188175
['2006-03-28', 'BUY', 'IBM', 1000.0, 45.0]]}
189176
```
190177

191-
### Execute a SCRIPT
178+
### Execute an SQL script
192179

193180
```python
194181
script = '''CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT, phone TEXT);
@@ -221,7 +208,7 @@ OUTPUT
221208
```
222209

223210

224-
### DROP a TABLE
211+
### DROP a Table
225212

226213
Note: In the default authorization setting, a client is not allowed to drop any table.
227214

@@ -238,6 +225,20 @@ OUTPUT
238225
'items': []}
239226
```
240227

228+
### SELECT statement; Table not present
229+
```python
230+
from pprint import pprint
231+
result = client.execute("SELECT * FROM IDOLS")
232+
pprint(result)
233+
234+
```
235+
OUTPUT
236+
```text
237+
{'error': {'message': 'sqlite3.OperationalError: no such table: IDOLS',
238+
'type': 'sqlite3.OperationalError'},
239+
'items': []}
240+
```
241+
241242
## Generic Default Authorization Policy
242243

243244

sqlite_rx/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.9.99"
1+
__version__ = "1.0.0"
22
__author__ = "Abhishek Singh"
33
__authoremail__ = "aosingh@asu.edu"
44

sqlite_rx/server.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,12 @@ def stream(self,
7979

8080
if use_encryption or use_zap:
8181

82-
server_curve_id = server_curve_id if server_curve_id else "id_server_{}_curve".format(
83-
socket.gethostname())
84-
keymonkey = KeyMonkey(
85-
key_id=server_curve_id,
86-
destination_dir=curve_dir)
82+
server_curve_id = server_curve_id if server_curve_id else "id_server_{}_curve".format(socket.gethostname())
83+
keymonkey = KeyMonkey(key_id=server_curve_id, destination_dir=curve_dir)
8784

8885
if use_encryption:
8986
LOG.info("Setting up encryption using CurveCP")
90-
self.socket = keymonkey.setup_secure_server(
91-
self.socket, address)
87+
self.socket = keymonkey.setup_secure_server(self.socket, address)
9288

9389
if use_zap:
9490
if not use_encryption:
@@ -241,18 +237,20 @@ def execute(self, message: dict, *args, **kwargs):
241237
"items": [],
242238
"error": error
243239
}
244-
if self._cursor.rowcount > -1:
245-
result['row_count'] = self._cursor.rowcount
246-
247240
if error:
248241
return zlib.compress(msgpack.dumps(result))
249242

250-
if self._cursor.lastrowid:
251-
result['lastrowid'] = self._cursor.lastrowid
252-
253243
try:
254-
result['items'] = [row for row in self._cursor.fetchall()]
244+
result['items'] = list(self._cursor.fetchall())
245+
# If rowcount attribute is set on the cursor object include it in the response
246+
if self._cursor.rowcount > -1:
247+
result['rowcount'] = self._cursor.rowcount
248+
# If lastrowid attribute is set on the cursor include it in the response
249+
if self._cursor.lastrowid:
250+
result['lastrowid'] = self._cursor.lastrowid
251+
255252
return zlib.compress(msgpack.dumps(result))
253+
256254
except Exception:
257255
LOG.exception("Exception while collecting rows")
258256
result['error'] = self.capture_exception()

sqlite_rx/tests/curezmq/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
LOG = logging.getLogger(__file__)
1919

20+
2021
@pytest.fixture(scope="module")
2122
def curvezmq_client():
2223
with get_server_auth_files() as auth_files:

sqlite_rx/tests/curezmq/test_queries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,6 @@ def test_table_rows_insertion(curvezmq_client):
5454
]
5555

5656
result = curvezmq_client.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', *purchases, execute_many=True)
57-
expected_result = {'error': None, 'items': [], 'row_count': 27}
57+
expected_result = {'error': None, 'items': [], 'rowcount': 27}
5858
assert result == expected_result
5959

sqlite_rx/tests/plain/test_queries.py

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def test_table_rows_insertion(plain_client):
3636
]
3737

3838
result = plain_client.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', *purchases, execute_many=True)
39-
expected_result = {'error': None, 'items': [], 'row_count': 27}
39+
expected_result = {'error': None, 'items': [], 'rowcount': 27}
4040
assert result == expected_result
4141

4242

@@ -45,13 +45,89 @@ def test_table_not_present(plain_client):
4545
assert type(result) == dict
4646

4747

48+
def test_select_before_update(plain_client):
49+
purchases = [['2006-03-28', 'BUY', 'IBM', 1000, 45.00],
50+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
51+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
52+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
53+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
54+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
55+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
56+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
57+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
58+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
59+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
60+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
61+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
62+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
63+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
64+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
65+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
66+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
67+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
68+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
69+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
70+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
71+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
72+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
73+
('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
74+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
75+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
76+
]
77+
result = plain_client.execute('SELECT * FROM stocks')
78+
expected_result = {'error': None, 'items': [list(purchase) for purchase in purchases], 'lastrowid': 27}
79+
assert result == expected_result
80+
81+
82+
def test_update(plain_client):
83+
args = ('IBM',)
84+
result = plain_client.execute('UPDATE stocks SET price = 480 where symbol = ?', *args)
85+
expected_result = {'error': None, 'items': [], 'lastrowid': 27, 'rowcount': 9}
86+
assert result == expected_result
87+
88+
89+
def test_select(plain_client):
90+
91+
purchases = [['2006-03-28', 'BUY', 'IBM', 1000, 480.00],
92+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
93+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
94+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
95+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
96+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
97+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
98+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
99+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
100+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
101+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
102+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
103+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
104+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
105+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
106+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
107+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
108+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
109+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
110+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
111+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
112+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
113+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
114+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
115+
('2006-03-28', 'BUY', 'IBM', 1000, 480.00),
116+
('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
117+
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
118+
]
119+
result = plain_client.execute('SELECT * FROM stocks')
120+
expected_result = {'error': None, 'items': [list(purchase) for purchase in purchases], 'lastrowid': 27}
121+
assert result == expected_result
122+
123+
48124
def test_sql_script(plain_client):
49125
script = '''CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT, phone TEXT);
50126
CREATE TABLE accounts(id INTEGER PRIMARY KEY, description TEXT);
51127
52128
INSERT INTO users(name, phone) VALUES ('John', '5557241'),
53129
('Adam', '5547874'), ('Jack', '5484522');'''
54-
expected_result = {"error": None, 'items': []}
130+
expected_result = {"error": None, 'items': [], 'lastrowid': 27}
55131
result = plain_client.execute(script, execute_script=True)
56132
assert expected_result == result
57133

sqlite_rx/tests/zap/test_queries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,5 @@ def test_table_rows_insertion(zap_client):
5353
('2006-04-06', 'SELL', 'XOM', 500, 53.00),
5454
]
5555
result = zap_client.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', *purchases, execute_many=True)
56-
expected_result = {'error': None, 'items': [], 'row_count': 27}
56+
expected_result = {'error': None, 'items': [], 'rowcount': 27}
5757
assert result == expected_result

0 commit comments

Comments
 (0)