on 62_python_dbapi help sign in
215 lines 7.2 kB history raw
1import websocket as ws
2#this websocket-client module supports both python 2.7 and 3.x- the "websockets" module supports python 3.4+ but relies on asyncio. It might be possible to mix the modules in this driver or it make more sense to create a separate python 3.4+ database driver.
3import exceptions
4import json
6apilevel = '2.0'
7threadsafety = 2
8paramstyle = None #not applicable
10class Error(exceptions.StandardError):
11 pass
13class Warning(exceptions.StandardError):
14 pass
16class InterfaceError(Error):
17 pass
19class DatabaseError(Error):
20 pass
22class InternalError(DatabaseError):
23 pass
25class OperationalError(DatabaseError):
26 pass
28class ProgrammingError(DatabaseError):
29 pass
31class IntegrityError(DatabaseError):
32 pass
34class DataError(DatabaseError):
35 pass
37class NotSupportedError(DatabaseError):
38 pass
40class ProjectM36Connection(object):
41 def __init__(self, proto, host, port, path, dbname):
42 assert proto in ('ws', 'wss'), "proto must be one of 'ws' or 'wss'"
43 self.proto = proto
44 self.host = host
45 self.port = port
46 self.path = path
47 self.dbname = dbname
48 self.conn = None
50 def connect(self):
51 port = ''
52 if self.port:
53 port = ':{}'.format(self.port)
55 path = ''
56 if self.path:
57 path = '/{}'.format(self.path)
60 self.conn = ws.create_connection('{}://{}{}{}'.format(self.proto,
61 self.host,
62 port,
63 path))
64 self.conn.send('connectdb:{}'.format(self.dbname))
65 result = self.conn.recv()
66 print result
68 result = self.conn.recv()
69 print result
71 return True
73 def close(self):
74 if self.conn is None: #already closed
75 raise ProgrammingError('attempt to close connection which was not open')
76 self.conn.close()
77 self.conn = None
79 def commit(self):
80 self.executeTutorialD(':commit')
82 def rollback(self):
83 self.executeTutorialD(':rollback')
85 def cursor(self):
86 return Cursor(self)
88 def _send(self, t):
89 print 'SEND:', t
90 return self.conn.send(t)
92 def _recv(self):
93 return self.conn.recv()
95class ProjectM36JSONEncoder(json.JSONEncoder):
96 def default(self, obj):
97 if isinstance(obj, RelationalExpr):
98 return obj.as_json()
99 else:
100 super(ProjectM36JSONEncoder, self).default(obj)
102class ProjectM36JSONDecoder(json.JSONDecoder):
103 def decode(self, s):
104 if
105 super(ProjectM36JSONDecoder, self).decode(s)
107class Cursor(object):
108 def __init__(self, conn):
109 self._arraysize = 1
110 self._conn = conn
112 @property
113 def description(self):
114 return []
116 @property
117 def rowcount(self):
118 return 0
120 #def callproc(self): #not applicable
122 def close(self):
123 return
125 def executeTutorialD(self, tutoriald):
126 self.conn.send()
128 def execute(self, relationalExpression):
129 relExprJson = json.dumps(relationalExpression, cls=ProjectM36JSONEncoder)
130 self._conn._send('evalrelexpr:{}'.format(relExprJson))
131 result = self._conn._recv()
132 rel = json.loads(result, cls=ProjectM36JSONDecoder)
133 return rel
135 def executemany(self, op, params):
136 raise NotImplementedError()
138 def fetchone(self):
139 return 0
141 def fetchmany(self):
142 return 0
144 def fetchall(self):
145 return 0
147 #def nextset(self): #not applicable
149 @property
150 def arraysize(self):
151 return self._arraysize
153 @arraysize.setter
154 def set_arraysize(self, size):
155 self._arraysize = size
157 def setinputsizes(self, sizes):
158 return
160 def setoutputsize(self, size, column):
161 return
163def connect(proto, host, port, path, dbname):
164 conn = ProjectM36Connection(proto, host, port, path, dbname)
165 conn.connect()
166 return conn
168class RelationalExpr(object):
169 def as_json(self):
170 return {'tag':self.__class__.__name__,
171 'contents':self.json_contents()}
173class RelationVariable(RelationalExpr):
174 def __init__(self, rvname):
175 self.name = rvname
177 def json_contents(self):
178 return [self.name, []]
180class Equals(RelationalExpr):
181 def __init__(self, exprA, exprB):
182 self.a = exprA
183 self.b = exprB
184'''
185(Maybe [AttributeExprBase a]) [TupleExprBase a] |
186 --- | Create and reference a relation from attributes and a tuple set.
187 MakeStaticRelation Attributes RelationTupleSet |
188 --- | Reference an existing relation in Haskell-space.
189 ExistingRelation Relation |
190 --MakeFunctionalRelation (creates a relation from a tuple-generating function, potentially infinite)
191 --in Tutorial D, relational variables pick up the type of the first relation assigned to them
192 --relational variables should also be able to be explicitly-typed like in Haskell
193 --- | Reference a relation variable by its name.
194 RelationVariable RelVarName a |
195 --- | Create a projection over attribute names. (Note that the 'AttributeNames' structure allows for the names to be inverted.)
196 Project AttributeNames (RelationalExprBase a) |
197 --- | Create a union of two relational expressions. The expressions should have identical attributes.
198 Union (RelationalExprBase a) (RelationalExprBase a) |
199 --- | Create a join of two relational expressions. The join occurs on attributes which are identical. If the expressions have no overlapping attributes, the join becomes a cross-product of both tuple sets.
200 Join (RelationalExprBase a) (RelationalExprBase a) |
201 --- | Rename an attribute (first argument) to another (second argument).
202 Rename AttributeName AttributeName (RelationalExprBase a) |
203 --- | Return a relation containing all tuples of the first argument which do not appear in the second argument (minus).
204 Difference (RelationalExprBase a) (RelationalExprBase a) |
205 --- | Create a sub-relation composed of the first argument's attributes which will become an attribute of the result expression. The unreferenced attributes are not altered in the result but duplicate tuples in the projection of the expression minus the attribute names are compressed into one. For more information, <https://github.com/agentm/project-m36/blob/master/docs/introduction_to_the_relational_algebra.markdown#group read the relational algebra tutorial.>
206 Group AttributeNames AttributeName (RelationalExprBase a) |
207 --- | Create an expression to unwrap a sub-relation contained within at an attribute's name. Note that this is not always an inverse of a group operation.
208 Ungroup AttributeName (RelationalExprBase a) |
209 --- | Filter the tuples of the relational expression to only retain the tuples which evaluate against the restriction predicate to true.
210 Restrict (RestrictionPredicateExprBase a) (RelationalExprBase a) |
211 --- | Returns the true relation iff
212 Equals (RelationalExprBase a) (RelationalExprBase a) |
213 NotEquals (RelationalExprBase a) (RelationalExprBase a) |
214 Extend (ExtendTupleExprBase a) (RelationalExprBase a)
215'''