-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[2020-09-05]添加sql_living用于对象化生成SQL语句
- Loading branch information
1 parent
225829f
commit c34aa7b
Showing
4 changed files
with
510 additions
and
210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.