Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagecell
Path: blob/master/db_sqlalchemy.py
447 views
1
"""
2
SQLAlchemy Database Adapter
3
---------------------------
4
"""
5
6
from datetime import datetime
7
import random
8
import string
9
10
from sqlalchemy import create_engine, Column, Integer, String, DateTime
11
from sqlalchemy.orm import declarative_base, sessionmaker
12
from sqlalchemy.exc import IntegrityError
13
14
import db
15
16
17
Base = declarative_base()
18
19
20
class ExecMessage(Base):
21
"""
22
Table of input messages in JSON form.
23
"""
24
__tablename__ = "permalinks"
25
ident = Column(String, primary_key=True, index=True)
26
code = Column(String)
27
language = Column(String)
28
interacts = Column(String)
29
created = Column(DateTime, default=datetime.utcnow)
30
last_accessed = Column(
31
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
32
requested = Column(Integer, default=0)
33
34
def __repr__(self):
35
return """\
36
ident: {}
37
Code:
38
{}
39
Interacts:
40
{}
41
Language: {}
42
Created: {}
43
Last accessed: {}
44
Requested: {}""".format(
45
self.ident,
46
self.code,
47
self.interacts,
48
self.language,
49
self.created,
50
self.last_accessed,
51
self.requested)
52
53
54
class DB(db.DB):
55
"""
56
SQLAlchemy database adapter
57
58
:arg db_file str: the SQLAlchemy URI for a database file
59
"""
60
61
def __init__(self, db_file):
62
self.engine = create_engine(db_file)
63
self.SQLSession = sessionmaker(bind=self.engine)
64
Base.metadata.create_all(self.engine)
65
self.dbsession = self.SQLSession()
66
67
async def add(self, code, language, interacts):
68
"""
69
See :meth:`db.DB.add`
70
"""
71
while True:
72
ident = "".join(
73
random.choice(string.ascii_lowercase) for _ in range(6))
74
message = ExecMessage(
75
ident=ident,
76
code=code,
77
language=language,
78
interacts=interacts)
79
try:
80
self.dbsession.add(message)
81
self.dbsession.commit()
82
except IntegrityError:
83
# ident was used before
84
self.dbsession.rollback()
85
else:
86
break
87
return ident
88
89
async def get(self, key):
90
"""
91
See :meth:`db.DB.get`
92
"""
93
msg = self.dbsession.query(ExecMessage).filter_by(ident=key).first()
94
if msg is None:
95
raise LookupError
96
msg.requested = ExecMessage.requested + 1
97
self.dbsession.commit()
98
return (msg.code, msg.language, msg.interacts)
99
100