文档章节

一个装饰器的例子

o
 osc_x4h57ch8
发布于 2018/04/24 12:03
字数 895
阅读 0
收藏 0

需求是:用文件的方式模拟select,insert 等操作 因为是模拟,不用数据库模块实现 用文件模拟数据库,记录形式是 id,name,dept,phoe,eroll_data记录到磁盘 支持select ,insert 等标准形式的sql语法 用了两个 模块实现需求 sql_func.py 用来执行sql操作 mock_sql.py用来解析用户的输入 其中,在mock_sql.py里面用了装饰器parse_user_input用来解析用户的输入,通过这个装饰器,得到用户不同的sql语句对应的表名,字段名,和限定条件(比如where 子句后面的条件),和insert 操作里的values的内容 用了反射的方法去匹配不同的insert/delete/update/select的具体函数 具体到sql_func.py里面实现的都是字符串解析,通过字符串解析获取内容,写入文件 sql_func里面的 read_file()函数实现读取文件,对应select功能 sql_func里面的get_last_line实现读取当前文件的最后一行的功能,这个是为了给insert用的 ,inser实现id自增,需要判断当前最后一行的id号 sql_func里面的write_file()函数实现写文件 文件名: sql_func.py

# coding:utf-8

import re
import os

def insert(action_name, dbname, fieldname, condition_limit, condition_values):
    print "action:", action_name, dbname, fieldname, condition_limit
    # insert into staff (name, dept, phone, eroll_date) values (li, DEV, 123456677, 20110101)
    write_file(dbname, fieldname, condition_limit, condition_values)

def delete(action_name, dbname, fieldname, condition_limit, condition_values):
    print "action:", action_name, dbname, fieldname, condition_limit

def update(action_name, dbname, fieldname, condition_limit, condition_values):
    print "action:", action_name, dbname, fieldname, condition_limit

def select(action_name, dbname, fieldname, condition_limit, condition_values):
    print "action:", action_name, dbname, fieldname, condition_limit
    read_file(dbname, fieldname, condition_limit)

def read_file(fname, fieldname, condition_limit):
    with open(fname, "r") as fd:
            for line in fd:
                if fieldname == "*" and condition_limit == "no":
                    print line.strip("\n")
                elif fieldname == "*" and condition_limit != "no":
                    condition_item = condition_limit.strip(";").split()[0].strip('"')
                    condition_signal = condition_limit.strip(";").split()[1]
                    condition_value = condition_limit.strip(";").split()[2].strip('"')
                    if condition_item == "name" and condition_signal == "=":
                        if line.strip("\n").split(",")[1] == condition_value:
                            print line.strip("\n")
                    elif condition_item == "dept":
                        if line.strip("\n").split(",")[2] == condition_value:
                            print line.strip("\n")
                    elif condition_item == "eroll_date" and condition_signal == "like":
                        if line.strip("\n").split(",")[4].__contains__(condition_value):
                            print line.strip("\n")


def get_last_line(fname):
    block_size = 1024
    with open(fname, "r") as fd:
        file_size = os.path.getsize(fname) 
        if file_size > block_size:
            seek_point = (file_size // block_size)
            fd.seek((seek_point - 1) * file_size)
        else:
            fd.seek(0, 0)
        lines = fd.readlines()
        if lines:
            last_line = lines[-1].strip()
        print last_line    
    return last_line

def write_file(fname, fieldname, condition_limit, condition_values):
    with open(fname ,"a+") as fd:
        last_line = get_last_line(fname) 
        cur_max_id = last_line.split(",")[0]
        print cur_max_id
        item = ",".join(condition_values.split(","))
        record = re.sub(r'"| ', "", item.strip()).strip("(").strip(")")
        record_id = int(cur_max_id) + 1
        fd.writelines(str(record_id) + "," + record)

文件名: mock_sql.py

# coding:utf-8

'''
sql_func是导入的另外一个模块,即位于同级目录的sql_func.py

需求语法:
    insert into tablename
    delete from tablename
    delete from tablename where clause
    update tablename set filedname=value
    update tablename set (fieldname1, fieldname2, fieldname3...) values (val1, val2, val3...)
    select * from tablename where clasuse
    select filedname from tablename where clause
'''

import re
import sql_func

def parse_user_rawinput(func):
    # 拆分字符串获得表名的正则表达式
    re_parse_dbname = r"' '+|from|update|into"
    # 拆分字符串获得字段名的正则表达式
    re_field_name = r"select|from|set|where|into|values|="
    # 拆分字符串获得where条件的正则表达式
    re_condition = r"where"
    # 拆分是insert into插入记录的情况下的values的正则表达式
    re_insert_values = r"values"
    def wrapper_parse(user_input):
        user_action_pointer, user_line, user_sql = func(user_input)
        if user_action_pointer in ["select", "delete","insert", "update"]:
            user_action_pointer, user_sql, user_line = func(user_input)
            dbname = re.split(re_parse_dbname, user_line)[1].lstrip().split()[0].rstrip(";")
            fieldname = re.sub(r"(^.* )\(", "", re.split(re_field_name, user_line)[1]).strip(" )")
            if user_action_pointer in ["select", "delete", "update"]:
                condition = re.split(re_condition, user_line)
                if len(condition) == 1:
                    condition_limit = "no"
                else:
                    condition_limit = condition[1]
            elif user_action_pointer == "insert":
                condition_limit = "no"
                condition_values = re.split(re_insert_values, user_line)[1]
            sql_action(user_action_pointer, dbname, fieldname, condition_limit, condition_values)
        else:
           print  "invalid action"
           return "invalid action"
           exit(1)
    return wrapper_parse

@parse_user_rawinput
def parse_user_input(user_input):
    user_action_pointer = user_input["user_sql_list"][0]
    user_sql = user_input["user_sql_list"]
    user_line = user_input["user_line"]
    return user_action_pointer, user_sql, user_line

def sql_action(action_name, dbname, fieldname, condition_limit, condition_values):
    if action_name in ["select", "insert", "update", "delete"]:
        if hasattr(sql_func, action_name):
            func = getattr(sql_func, action_name)
            result = func(action_name, dbname, fieldname, condition_limit, condition_values)

def input():
    user_results = dict()
    user_line = raw_input("input your sql:")
    user_sql_list = user_line.rstrip(";").split()
    user_results["user_line"] = user_line
    user_results["user_sql_list"] = user_sql_list
    return user_results

if __name__ == "__main__":
    user_input = input()
    parse_user_input(user_input)

1,zhang,DEV,13600010001,20100101 2,wang,DEV,1360020002,20110101 3,zhao,OPS,13600030005,20110201 4,qian,OPS,13600040006,20130203 5,sun,OPS,13600050007,20070709 6,li,OPS,13600060008,20150602 7,wu,OPS,13600070009,20160703

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

Vue+Spring Data JPA+MySQL 增查改删

视频讲解: https://www.bilibili.com/video/BV16i4y1G7i2/ 工程概述: 前后端分离,进行简单增查改删(CRUD) 前端使用VUE 后端使用Spring Data JPA 数据库使用MySQL #EmployeeController.jav...

潘文海
38分钟前
13
0
我花了一个星期,做出了公司的管理系统,只需几个步骤!

我是企业的管理人员,公司发展到现阶段,感觉进入到了瓶颈期,每个员工的工作都已经饱和,很难再挤出时间做其它的事情,需要一款合适的管理软件来协作我们的工作。本来打算买一套管理软件就行...

科技那些事儿
42分钟前
19
0
如何从Android应用程序获取崩溃数据? - How do I obtain crash-data from my Android application?

问题: How can I get crash data (stack traces at least) from my Android application? 如何从我的Android应用程序获取崩溃数据(至少是堆栈跟踪)? At least when working on my own de......

技术盛宴
52分钟前
16
0
使用telnet测试指定端口的连通性

大家好,我是良许。 大家知道,telnet 是一个阉割版的 ssh ,它数据不加密,数据容易被盗窃,也容易受中间人攻击,所以默认情况下 telnet 端口是必须要被关闭的。 telnet为用户提供了在本地计...

良许Linux
56分钟前
13
0
创建python项目-从0到1开始Django第二篇

接上一篇:基于Centos7系统Django环境搭建-从0到1开始Django第一篇 https://my.oschina.net/guiguketang/blog/4333406 1.项目初始化 #django-admin startproject mysite 2.启动服务,执行man...

硅谷课堂
今天
29
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部