pythonorm

pythonorm Git Source Tree


Root/orm.py

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

Archive Download this file

Branches

Number of commits:
Page rendered in 0.22508s using 11 queries.