33 lines
1.4 KiB
Markdown
33 lines
1.4 KiB
Markdown
# Server
|
|
```python
|
|
def SQL():
|
|
import sqlite3, hashlib, os; con = sqlite3.connect('.db', isolation_level=None)
|
|
sql = lambda q, *p: list(con.execute(q, p))
|
|
if not os.path.exists('.db-blob') and os.mkdir('.db-blob') is None:
|
|
con.executescript('''PRAGMA journal_mode=WAL;
|
|
CREATE TABLE kv(k, v, t DEFAULT CURRENT_TIMESTAMP);
|
|
CREATE INDEX idx_kv_v ON kv(v); CREATE INDEX idx_kv_k_t ON kv(k,t DESC)''')
|
|
def setitem(_, filename, blob):
|
|
if not sql('SELECT 1 FROM kv WHERE v=?', sha1 := hashlib.sha1(blob).hexdigest()):
|
|
with open(f'.db-blob/{sha1}', 'xb') as f: f.write(blob)
|
|
sql('INSERT INTO kv(k,v) VALUES(?,?)', filename, sha1)
|
|
def getitem(_, filename):
|
|
if sha1 := sql('SELECT v FROM kv WHERE k=? ORDER BY t DESC', filename):
|
|
return open(f'.db-blob/{sha1[0][0]}', 'rb').read()
|
|
return type('', (), dict(__setitem__=setitem, __getitem__=getitem))()
|
|
sql = SQL()
|
|
|
|
import zmq; (socket := zmq.Context().socket(zmq.REP)).bind('tcp://*:5555')
|
|
while True:
|
|
filename, blob = socket.recv_pyobj()
|
|
sql[filename] = blob
|
|
socket.send_string('OK')
|
|
```
|
|
|
|
# Client
|
|
```python
|
|
def put(filename, blob, addr='tcp://localhost:5555'):
|
|
import zmq; (socket := zmq.Context().socket(zmq.REQ)).connect(addr)
|
|
assert socket.send_pyobj((filename, blob)) or socket.recv_string() == 'OK'
|
|
put('hello', b'world')
|
|
``` |