Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 34 additions & 7 deletions datomic.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# -*- coding: utf-8 -*-
import httplib
import httplib2
import urllib
from urlparse import urljoin
from edn import loads
import requests

import sys
if 'gevent' in sys.modules:
import gevent
import grequests as requests
else:
gevent = None
import requests
import inspect
import pprint
class Database(object):
def __init__(self, name, conn):
self.name = name
Expand All @@ -23,32 +30,52 @@ def __init__(self, location, storage):
def db_url(self, dbname):
return urljoin(self.location, 'data/') + self.storage + '/' + dbname

def create_database(self, dbname):
def create_database(self, dbname, stream=False, size=None):
r = requests.post(self.db_url(''), data={'db-name':dbname})
if gevent:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing this, you probably want to abstract out the transport layer from the database, and pass the transport in Database.init().

pool = Pool(size) if size else None
jobs = [requests.send(r, pool, stream=stream)]
gevent.joinall(jobs)
r = r.response
assert r.status_code in (200, 201), r.text
return Database(dbname, self)

def transact(self, dbname, data):
def transact(self, dbname, data, stream=False, size=None):
data = '[%s\n]' % '\n'.join(data)
r = requests.post(self.db_url(dbname)+'/', data={'tx-data':data},
headers={'Accept':'application/edn'})
if gevent:
pool = Pool(size) if size else None
jobs = [requests.send(r, pool, stream=stream)]
gevent.joinall(jobs)
r = r.response
assert r.status_code in (200, 201), (r.status_code, r.text)
return loads(r.content)

def query(self, dbname, query, extra_args=[], history=False):
def query(self, dbname, query, extra_args=[], history=False, stream=False, size=None):
args = '[{:db/alias ' + self.storage + '/' + dbname
if history:
args += ' :history true'
args += '} ' + ' '.join(str(a) for a in extra_args) + ']'
r = requests.get(urljoin(self.location, 'api/query'),
params={'args' : args, 'q':query},
headers={'Accept':'application/edn'})
if gevent:
pool = Pool(size) if size else None
jobs = [requests.send(r, pool, stream=stream)]
gevent.joinall(jobs)
r = r.response
assert r.status_code == 200, r.text
return loads(r.content)

def entity(self, dbname, eid):
def entity(self, dbname, eid, stream=False, size=None):
r = requests.get(self.db_url(dbname) + '/-/entity', params={'e':eid},
headers={'Accept':'application/edn'})
if gevent:
pool = Pool(size) if size else None
jobs = [requests.send(r, pool, stream=stream)]
gevent.joinall(jobs)
r = r.response
assert r.status_code == 200
return loads(r.content)

Expand Down
33 changes: 29 additions & 4 deletions edn.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ def inst_handler(time_string):

tag_handlers = {'inst':inst_handler,
'uuid':UUID,
'db/fn':lambda x:x}
'db/fn':lambda x:x,
'db/id':lambda x:x}

@coroutine
def tag_handler(tag_name):
Expand Down Expand Up @@ -90,6 +91,16 @@ def symbol_handler(s):
else:
s += c

CHAR_MAP = {
"a": "\a",
"b": "\b",
"f": "\f",
"n": "\n",
"r": "\r",
"t": "\t",
"v": "\v"
}

@coroutine
def parser(target, stop=None):
handler = None
Expand Down Expand Up @@ -123,7 +134,12 @@ def parser(target, stop=None):
while 1:
char = (yield)
if char == '\\':
chars.append((yield))
char = (yield)
char2 = CHAR_MAP.get(char)
if char2 != None:
chars.append(char2)
else:
chars.append(char)
elif char == '"':
target.send(''.join(chars))
break
Expand Down Expand Up @@ -158,7 +174,16 @@ def parser(target, stop=None):
if c in '[(':
target.send(tuple(l))
elif c == '#':
target.send(frozenset(l))
if isinstance(l, list):
m=[]
for item in l:
if hasattr(item, 'get'):
m.append(item.get(':db/id'))
else:
m.append(item)
target.send(frozenset(m))
else:
target.send(frozenset(l))
else:
if len(l)%2:
raise Exception("Map literal must contain an even number of elements")
Expand All @@ -177,7 +202,7 @@ def loads(s):
return l[0]

if __name__ == '__main__':
print loads(b'(:graham/stratton true \n , "A string with \\"s" true #uuid "f81d4fae7dec11d0a76500a0c91e6bf6")')
print loads(b'(:graham/stratton true \n , "A string with \\n \\"s" true #uuid "f81d4fae7dec11d0a76500a0c91e6bf6")')
print loads(b'[\space \\\xE2\x82\xAC [true []] ;true\n[true #inst "2012-09-10T23:39:43.309-00:00" true ""]]')
print loads(b' {true false nil [true, ()] 6 {#{nil false} {nil \\newline} }}')
print loads(b'[#{6.22e-18, -3.1415, 1} true #graham #{"pie" "chips"} "work"]')
Expand Down