from enum import enum␊ |
from pluralize import pluralize␊ |
import pymysql␊ |
␊ |
SQL_OPERATION = enum("SQL_SELECT", "SQL_UPDATE", "SQL_DELETE", "SQL_INSERT", "SQL_NULL")␊ |
BOOL_OPERATION = enum("OP_AND", "OP_OR", "OP_NULL")␊ |
GROUP_OPERATION = enum("LEFT_PARAN", "RIGHT_PARAN", "NULL_PARAM")␊ |
␊ |
class Model(object):␊ |
␊ |
_has_many = []␊ |
_has_one = []␊ |
_related = []␊ |
_related_field = []␊ |
␊ |
_operation = SQL_OPERATION.SQL_NULL␊ |
␊ |
␊ |
class condition:␊ |
operation = BOOL_OPERATION.OP_NULL␊ |
next_cond = None␊ |
group = False␊ |
clause = ""␊ |
def __init__(self, op, clause, group=GROUP_OPERATION.NULL_PARAM):␊ |
self.operation = op␊ |
self.clause = clause␊ |
self.group = group␊ |
self.clause = clause␊ |
␊ |
␊ |
␊ |
"""␊ |
users␊ |
flavors␊ |
user_flavors␊ |
␊ |
SELECT {FIELDS} FROM users␊ |
INNER JOIN user_flavors ON user_flavors.user_id = users.id␊ |
INNER JOIN flavors ON user_flavors.flavor_id = flavors.id␊ |
␊ |
SELECT {FIELDS} FROM self.tblname␊ |
INNER JOIN self.tblname_model.tblname ON self.tblname_model.tblname.self.tblname_id = self.tblname.id␊ |
INNER JOIN model.tblname ON self.tblname_model.tblname.model.tblname_id = model.tblname.id␊ |
"""␊ |
_has_many_to_many = []␊ |
␊ |
␊ |
def select(self, field, fas=None):␊ |
return self␊ |
␊ |
def select_related(self, model, fields):␊ |
return self␊ |
␊ |
def where(self, field, value=None):␊ |
return self␊ |
␊ |
def or_where(self, field, value=None):␊ |
return self␊ |
␊ |
def where_in(self, field, value):␊ |
return self␊ |
␊ |
def or_where_in(self, field, value=None):␊ |
return self␊ |
␊ |
def where_not_in(self, field, value=None):␊ |
return self␊ |
␊ |
def or_where_not_in(self, field, value=None):␊ |
return self␊ |
␊ |
def from_array(self, POST, keys):␊ |
return self␊ |
␊ |
def like(self, field, value):␊ |
return self␊ |
␊ |
def or_like(self, field, value):␊ |
return self␊ |
␊ |
def not_like(self, field, value):␊ |
return self␊ |
␊ |
def or_not_like(self, field, value):␊ |
return self␊ |
␊ |
def ilike(self, field, value):␊ |
return self␊ |
␊ |
def or_ilike(self, field, value):␊ |
return self␊ |
␊ |
def not_ilike(self, field, value):␊ |
return self␊ |
␊ |
def or_not_ilike(self, field, value):␊ |
return self␊ |
␊ |
def limit(self, limit, start=0):␊ |
return self␊ |
␊ |
def order_by(self):␊ |
return self␊ |
␊ |
def select_max(self):␊ |
return self␊ |
␊ |
def select_min(self):␊ |
return self␊ |
␊ |
def select_avg(self):␊ |
return self␊ |
␊ |
def select_sum(self):␊ |
return self␊ |
␊ |
def distinct(self):␊ |
return self␊ |
␊ |
def group_by(self):␊ |
return self␊ |
␊ |
def having(self):␊ |
return self␊ |
␊ |
def where_related(self, model, field):␊ |
return self␊ |
␊ |
def save(self, force=False):␊ |
return []␊ |
␊ |
def delete(self):␊ |
return []␊ |
␊ |
def get(self):␊ |
return []␊ |
␊ |
def query(self):␊ |
"""␊ |
This method should be overwritten in child classes␊ |
"""␊ |
raise NotImplementedError("Abstract method")␊ |
␊ |
class SQLModel(Model):␊ |
"""␊ |
@type self._where: Model.condition␊ |
"""␊ |
_select = {}␊ |
_where = None␊ |
_resulting_query = ""␊ |
_select_related = {}␊ |
def select(self, field, fas=None):␊ |
if fas:␊ |
self._select[field] = fas␊ |
else:␊ |
self._select[field] = field␊ |
return self␊ |
␊ |
def select_related(self, model, fields):␊ |
if self._select_related.has_key(model):␊ |
self._select_related[model].append(fields)␊ |
else:␊ |
self._select_related[model] = fields␊ |
return self␊ |
␊ |
␊ |
def _where_abs(self, field, value, op):␊ |
if value:␊ |
if type(value) == type(0):␊ |
value = str(value)␊ |
else:␊ |
value = "'" + value + "'"␊ |
if " " in field:␊ |
cond = Model.condition(op, field + " " + value)␊ |
else:␊ |
cond = Model.condition(op, field + " = " + value)␊ |
else:␊ |
cond = Model.condition(op, field)␊ |
if self._where:␊ |
next = self._where␊ |
while next:␊ |
if not next.next_cond:␊ |
break␊ |
next = next.next_cond␊ |
next.next_cond = cond␊ |
else:␊ |
self._where = cond␊ |
␊ |
def _build_where(self):␊ |
pointer = self._where␊ |
if pointer:␊ |
self._resulting_query += "WHERE "␊ |
while pointer:␊ |
if pointer.group is not None and pointer.group != GROUP_OPERATION.NULL_PARAM:␊ |
if pointer.group == GROUP_OPERATION.LEFT_PARAN:␊ |
self._resulting_query += "( "␊ |
elif pointer.group == GROUP_OPERATION.RIGHT_PARAN:␊ |
self._resulting_query += ") "␊ |
else:␊ |
self._resulting_query += pointer.clause + " "␊ |
if pointer.next_cond:␊ |
if pointer.operation == BOOL_OPERATION.OP_AND:␊ |
self._resulting_query += "AND "␊ |
elif pointer.operation == BOOL_OPERATION.OP_OR:␊ |
self._resulting_query += "OR "␊ |
␊ |
pointer = pointer.next_cond␊ |
␊ |
␊ |
def where(self, field, value=None):␊ |
self._where_abs(field, value, BOOL_OPERATION.OP_AND)␊ |
return self␊ |
␊ |
def where_in(self, field, value):␊ |
self._where_abs(field + " IN (" + ",".join([str(v) for v in value]) + ")", None, BOOL_OPERATION.OP_AND)␊ |
return self␊ |
␊ |
def or_where(self, field, value=None):␊ |
self._where_abs(field, value, BOOL_OPERATION.OP_OR)␊ |
return self␊ |
␊ |
def save(self, force=False):␊ |
props = dir(self)␊ |
tblname = pluralize(type(self).__name__)␊ |
propdict = {}␊ |
id = None␊ |
if type(self).__name__ + "_id" in props:␊ |
id = getattr(self, type(self).__name__ + "_id")␊ |
␊ |
for prop in self._select:␊ |
attr = getattr(self, prop)␊ |
if prop[0] == '_':␊ |
continue␊ |
propdict[prop] = getattr(self, prop)␊ |
␊ |
if id is not None:␊ |
self._resulting_query = "UPDATE " + tblname + " SET "␊ |
for k,v in propdict.iteritems():␊ |
if type(v) == type(0):␊ |
self._resulting_query += k + " = " + v + ", "␊ |
elif type(v) == type(""):␊ |
self._resulting_query += k + " = '" + v + "', "␊ |
self._resulting_query = self._resulting_query.rstrip(', ') + " "␊ |
self._build_where()␊ |
if "WHERE" in self._resulting_query:␊ |
self._resulting_query += "AND " + tblname + ".id = " + str(id) + " "␊ |
else:␊ |
self._resulting_query += "WHERE " + tblname + ".id = " + str(id) + " "␊ |
else:␊ |
self._resulting_query = "INSERT INTO " + tblname + " "␊ |
self._resulting_query += "("␊ |
for key in propdict.keys():␊ |
self._resulting_query += key + ","␊ |
self._resulting_query = self._resulting_query.rstrip(', ') + " "␊ |
self._resulting_query += ") VALUES ("␊ |
for val in propdict.values():␊ |
if type(val) == type(0):␊ |
self._resulting_query += str(val) + ","␊ |
else:␊ |
self._resulting_query += "'" + val + "',"␊ |
self._resulting_query = self._resulting_query.rstrip(', ') + " "␊ |
self._resulting_query += ")"␊ |
return self._resulting_query␊ |
␊ |
␊ |
def get(self):␊ |
␊ |
self._resulting_query = "SELECT "␊ |
self._resulting_query += pluralize(type(self).__name__) + ".id AS " + type(self).__name__ + "_id, "␊ |
for tbl in self._has_one:␊ |
self._resulting_query += pluralize(type(tbl).__name__) + ".id AS " + type(tbl).__name__ + "_id, "␊ |
if self._select:␊ |
for k,v in self._select.iteritems():␊ |
if v:␊ |
self._resulting_query += "%s AS %s, " % (k, v)␊ |
else:␊ |
self._resulting_query += k + " "␊ |
for i in self._select_related:␊ |
self._resulting_query += i + ", "␊ |
self._resulting_query = self._resulting_query.strip(", ") + " "␊ |
else:␊ |
self._resulting_query += "* "␊ |
␊ |
self._resulting_query += "FROM " + pluralize(type(self).__name__) + " "␊ |
␊ |
for tbl in self._has_many:␊ |
tblname = pluralize(type(tbl).__name__)␊ |
single = type(tbl).__name__␊ |
self._resulting_query += "INNER JOIN %s ON %s = %s" % (tblname,␊ |
tblname + "." + type(self).__name__ + "_id",␊ |
type(self).__name__ + ".id") + " "␊ |
for tbl in self._has_one:␊ |
tblname = pluralize(type(tbl).__name__)␊ |
single = type(tbl).__name__␊ |
self._resulting_query += "INNER JOIN %s ON %s = %s" % (tblname,␊ |
pluralize(type(self).__name__) + "." + single + "_id",␊ |
tblname + ".id") + " "␊ |
for tbl in self._has_many_to_many:␊ |
jointbl = type(self).__name__ + "_" + pluralize(type(tbl).__name__)␊ |
thissingle = type(self).__name__␊ |
thisplural = pluralize(type(self).__name__)␊ |
tblsingle = type(tbl).__name__␊ |
tblplural = pluralize(type(tbl).__name__)␊ |
self._resulting_query += "INNER JOIN %s ON %s = %s" % (jointbl,␊ |
jointbl + "." + thissingle + "_id",␊ |
thisplural + ".id") + " "␊ |
self._resulting_query += "INNER JOIN %s ON %s = %s" % (tblplural,␊ |
jointbl + "." + tblsingle + "_id",␊ |
tblplural + ".id") + " "␊ |
␊ |
self._build_where()␊ |
␊ |
␊ |
return self._resulting_query␊ |
␊ |
class MySQLModel(SQLModel):␊ |
def connect(self, host='127.0.0.1', port=3306, user='root', passwd='', db='mysql'):␊ |
self.conn = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=db)␊ |
self.res = None␊ |
␊ |
␊ |
def save(self, force=False):␊ |
query = super(MySQLModel, self).save(force)␊ |
c = self.conn.cursor()␊ |
c.execute(query)␊ |
self.conn.commit()␊ |
c.close()␊ |
␊ |
def get(self):␊ |
if not self.res:␊ |
query = super(MySQLModel, self).get()␊ |
self.c = self.conn.cursor(pymysql.cursors.DictCursor)␊ |
self.c.execute(query)␊ |
self.res = self.c.fetchone()␊ |
␊ |
if not self.res:␊ |
#self._select = {}␊ |
self._where = None␊ |
self.c.close()␊ |
return None␊ |
␊ |
if self._select == {}:␊ |
if self.res:␊ |
for k,v in self.res.iteritems():␊ |
setattr(self, k, v)␊ |
res = self.c.fetchone()␊ |
else:␊ |
for i in self._select:␊ |
if i in self.res:␊ |
setattr(self, i, self.res[i])␊ |
setattr(self, type(self).__name__ + "_id", self.res[type(self).__name__ + "_id"])␊ |
for k,v in self._select_related.iteritems():␊ |
for i in self._has_one:␊ |
if type(i).__name__ == k:␊ |
i._select = {}␊ |
setattr(self, type(i).__name__, i)␊ |
for val in v:␊ |
i._select[val] = val␊ |
setattr(i, val, self.res[val])␊ |
setattr(i, type(i).__name__ + "_id", self.res[type(i).__name__ + "_id"])␊ |
␊ |
return True␊ |
␊ |
␊ |
␊ |
class CSVModel(Model):␊ |
pass␊ |