Skip to content

Commit

Permalink
[2020-09-05]添加sql_living用于对象化生成SQL语句
Browse files Browse the repository at this point in the history
  • Loading branch information
SystemLight committed Sep 5, 2020
1 parent 225829f commit c34aa7b
Show file tree
Hide file tree
Showing 4 changed files with 510 additions and 210 deletions.
216 changes: 6 additions & 210 deletions madtornado4/core/sql_living/__init__.py
Original file line number Diff line number Diff line change
@@ -1,212 +1,8 @@
from abc import ABC, abstractmethod
from typing import Union, Optional, TypeVar, List
from core.sql_living import directives, member

SQL = directives.SQL
build_sql = directives.build_sql

class RenderBasic(ABC):

def render(self) -> str:
raise NotImplementedError()


class ConditionBasic(RenderBasic):

@abstractmethod
def c_or(self, condition) -> "Condition":
raise NotImplementedError()

@abstractmethod
def c_and(self, condition) -> "Condition":
raise NotImplementedError()


class SQL(RenderBasic):

def __init__(self):
pass

@staticmethod
def from_sql(sql: str):
return SQL()

@staticmethod
def from_model(model):
return SQL()

def select(self, fields=None, table=None):
return Select(self)

def sql(self) -> str:
pass

def render(self) -> str:
pass


class Select(RenderBasic):

def __init__(self, sql_parent: SQL):
self.sql_parent = sql_parent

def where(self) -> "Where":
pass

def group_by(self) -> "GroupBy":
pass

def order_by(self) -> "OrderBy":
pass

def having(self) -> "Having":
pass

def limit(self) -> "Limit":
pass

def render(self) -> str:
pass


class Where(RenderBasic):

def __init__(self, sql_parent: SQL):
self.sql_parent = sql_parent

def group_by(self) -> "GroupBy":
pass

def order_by(self) -> "OrderBy":
pass

def having(self) -> "Having":
pass

def limit(self) -> "Limit":
pass

def render(self) -> str:
pass


class GroupBy(RenderBasic):

def __init__(self, sql_parent: SQL):
pass

def order_by(self) -> "OrderBy":
pass

def having(self) -> "Having":
pass

def limit(self) -> "Limit":
pass

def render(self) -> str:
pass


class OrderBy(RenderBasic):
"""
排序指令,包含desc和asc两个可选参数值
"""

def __init__(self, sql_parent: SQL):
pass

def having(self) -> "Having":
pass

def limit(self) -> "Limit":
pass

def render(self) -> str:
pass


class Having(RenderBasic):
"""
聚合函数条件运算
"""

def __init__(self, sql_parent: SQL):
pass

def limit(self) -> "Limit":
pass

def render(self) -> str:
pass


class Limit(RenderBasic):
def __init__(self, sql_parent: SQL):
pass

def render(self) -> str:
pass


class FieldNull:
pass


class Field(RenderBasic):

def __init__(self, name: str, value=FieldNull):
self.value = value

def sum(self) -> "Field":
return self

def count(self) -> "Field":
return self

def max(self) -> "Field":
return self

def min(self) -> "Field":
return self

def avg(self) -> "Field":
return self

def v(self, val=None) -> "Field":
self.value = val
return self

def render(self) -> str:
pass


class ConditionGroup(ConditionBasic):

def __init__(self, condition: "Condition"):
pass

def c_or(self, condition) -> "Condition":
pass

def c_and(self, condition) -> "Condition":
pass

def render(self) -> str:
pass


class Condition(ConditionBasic):

def __init__(self, field: "Field"):
self.field = field

def c_or(self, condition) -> "Condition":
pass

def c_and(self, condition) -> "Condition":
pass

def render(self) -> str:
pass
CG = member.ConditionGroup
C = member.Condition
F = member.Field
165 changes: 165 additions & 0 deletions madtornado4/core/sql_living/directives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
from core.sql_living import pick, member

from abc import ABC, abstractmethod
from typing import Optional


class InvalidDirectivesError(Exception):
pass


class DirectivesBasic(ABC):

def __init__(self, table: str, fields: Optional[pick.DirectiveField] = None):
self.fields = fields
self.table = table
self.pick = None
self.template = None
self.extra = {}

def where(self, condition: member.ConditionBasic) -> "pick.Where":
self.pick = pick.Where(condition)
return self.pick

def group_by(self, condition: member.ConditionBasic) -> "pick.GroupBy":
raise InvalidDirectivesError()

def order_by(self, condition, sort: str) -> "pick.OrderBy":
raise InvalidDirectivesError()

def having(self, condition: member.ConditionBasic) -> "pick.Having":
raise InvalidDirectivesError()

def limit(self, count: int, start: int = 0) -> "pick.Limit":
raise InvalidDirectivesError()

@abstractmethod
def render_fields(self, field: "member.Field") -> str:
raise NotImplementedError()

def render(self) -> str:
fields_str = ""
if isinstance(self.fields, list):
fields_list = []
for f in self.fields:
fields_list.append(self.render_fields(f))
fields_str = ",".join(fields_list)

if not fields_str:
fields_str = "*"
result = self.template.format(fields=fields_str, table=self.table, **self.extra)
if self.pick is not None:
result += self.pick.render()
return result


def build_sql(sql: str) -> "SQL":
return SQL()


class SQL:

def __init__(self):
self.directives = None # type: Optional[DirectivesBasic]

def select(self, table: str, fields: pick.DirectiveField = None) -> "Select":
self.directives = Select(table, fields)
return self.directives

def insert(self, table: str, fields: pick.DirectiveField = None) -> "Insert":
self.directives = Insert(table, fields)
return self.directives

def update(self, table: str, fields: pick.DirectiveField = None) -> "Update":
self.directives = Update(table, fields)
return self.directives

def delete(self, table: str) -> "Delete":
self.directives = Delete(table)
return self.directives

def sql(self) -> str:
if self.directives is None:
raise TypeError("空的指令")
return self.directives.render()


class Select(DirectivesBasic):

def __init__(self, table: str, fields: Optional[pick.DirectiveField] = None):
super().__init__(table, fields)
self.template = "select {fields} from {table}"

def group_by(self, condition: member.ConditionBasic) -> "pick.GroupBy":
self.pick = pick.GroupBy(condition)
return self.pick

def order_by(self, condition, sort: str) -> "pick.OrderBy":
self.pick = pick.OrderBy(condition, sort)
return self.pick

def having(self, condition: member.ConditionBasic) -> "pick.Having":
self.pick = pick.Having(condition)
return self.pick

def limit(self, count: int, start: int = 0) -> "pick.Limit":
self.pick = pick.Limit(count, start)
return self.pick

def render_fields(self, field: "member.Field") -> str:
return member.render_pure_field(field)


class Insert(DirectivesBasic):

def __init__(self, table: str, fields: Optional[pick.DirectiveField] = None):
super().__init__(table, fields)
self.template = "insert into {table} {fields} values ({values})"

def render_fields(self, field: "member.Field") -> str:
return member.render_pure_field(field)

def render(self) -> str:
fields_str = ""
values = []
if isinstance(self.fields, list):
fields_list = []
for f in self.fields:
if not f.value:
continue
fields_list.append(f.name)
values.append("'" + str(f.value) + "'")
fields_str = ",".join(fields_list)

fields_str = "(" + fields_str + ")" if fields_str else ""

result = self.template.format(fields=fields_str, table=self.table, values=",".join(values))
if self.pick is not None:
result += self.pick.render()
return result


class Update(DirectivesBasic):

def __init__(self, table: str, fields: Optional[pick.DirectiveField] = None):
super().__init__(table, fields)
self.template = "update {table} set {fields}"

def render_fields(self, field: "member.Field") -> str:
return member.render_condition_field(field, True)


class Delete(DirectivesBasic):

def __init__(self, table: str):
self.table = table
self.template = "delete from {table}"

def render_fields(self, field: "member.Field") -> str:
return member.render_pure_field(field)

def render(self) -> str:
result = self.template.format(table=self.table)
if self.pick is not None:
result += self.pick.render()
return result
Loading

0 comments on commit c34aa7b

Please sign in to comment.