diff --git a/www/app.py b/www/app.py new file mode 100644 index 0000000..bb8cfbe --- /dev/null +++ b/www/app.py @@ -0,0 +1,21 @@ +import logging;logging.basicConfig(level=logging.INFO) + +import asyncio,os,json,time +from datetime import datetime + +from aiohttp import web + +def index(request): + return web.Response(body=b'

Awesome

') + +@asyncio.coroutine +def init(loop): + app = web.Application(loop=loop) + app.router.add_route('GET','/',index) + srv = yield from loop.create_server(app.make_handler(),'127.0.0.1',9000) + logging.info('server started at http://127.0.0.1:9000') + return srv + +loop = asyncio.get_event_loop() +loop.run_until_complete(init(loop)) +loop.run_forever() diff --git a/www/orm.py b/www/orm.py new file mode 100644 index 0000000..83fdace --- /dev/null +++ b/www/orm.py @@ -0,0 +1,141 @@ +@asyncio.coroutine +def create_pool(loop,**kw): + logging.info('create database connection pool...') + global __pool + __pool = yield from aiomysql.create_pool( + host=kw.get('host','localhost'), + port=kw.get('port',3306), + user=kw['user'], + password=kw['password'], + db=kw['db'], + charset=kw.get('charset','utf8'), + autocommit=kw.get('autocommit',True), + maxsize=kw.get('maxsize',10), + minsize=kw.get('minsize',1), + loop=loop + ) + +@asyncio.coroutine +def select(sql,args,size=None): + log(sql,args) + global __pool + with(yield from __pool)as conn: + cur = yield from conn.cursor(aiomysql.DictCursor) + yield from cur.execute(sql.replace('?','%s'),args or()) + if size : + rs = yield from cur.fetchmany(size) + else: + rs = yield from cur.fatchall() + yield from cur.close() + logging.info('row return:%s' % len(rs)) + return rs + + +@asyncio.coroutine +def execute(sql,args): + log(sql) + with(yield from __pool)as conn: + try: + cur = yield from conn.cursor() + yield from cur.execute(sql.replace('?','%s'),args) + affected = cur.rowcount + yield from cur.close() + except BaseException as e: + raise + return affected + + +from orm import Model,StringField,IntegerField + +class User(Model): + __table__='users' + + id = IntegerField(primary_key=True) + name = StringField() + +class Model(dict,metaclass=ModelMetaclass): + + def __init__(self, **kw): + super(Model, self).__init__(**kw) + + def __getattr__(self,key): + try: + return self[key] + except KeyError: + raise AttributeError(r"'Model' object has no attribute '%s'" %key) + + def __getattr__(self,key,value): + self[key]=value + + def getValue(self,key): + return getattr(self,key,None) + + def getValueOrDefault(self,key): + value = getattr(self,key,None) + if value is None: + field = self.__mappings__[key] + if field.default is not None: + value = field.default() if callable(field.default) else field.default + logging.debug('using default value for %s:%s' %(key ,str(value))) + setattr(self,key,value) + return value + + +class Field(object): + + def __init__(self,name,column_type,primary_key,default): + self.name = name + self.column_type = column_type + self.primary_key = primary_key + self.default = default + + def __str__(self): + return '<%s,%s:%s>' %(self.__class__.__name,self.column_type,self.name) + + +class StringField(Field): + + def __int__(self,name=None,primary_key=False,default=None,ddl='varvhar(100)'): + super().__int__(name,ddl,primary_key,default) + + +class ModelMetaclass(type): + + def __new__(cls,name,bases,attrs): + #排除Model类本身 + if name=='Model': + return type.__new__(cls,name,bases,attrs) + #获取table名称 + tableName = attrs.get('__table__',None) or name + logging.info('found model :$s (table:%s)'%(name,tableName)) + #获取所有的Field和主键名 + mappings = dict() + fields = [] + primarykey = None + for k,v in attrs.items(): + if isinstance(v,Field): + logging.info(' found mapping:%s' % (k,v)) + mappings[k] = v + if v.primary_key: + #找到主键: + if primarykey: + raise RuntimeError('Dulplicate primary key for field:%s'%k) + primarykey=k + else: + fields.append(k) + if not primarykey: + raise RuntimeError('Primary key not found') + for k in mappings.keys(): + attrs.pop(k) + escaped_fields = list(map(lambda f: '`%s`'%f,fields)) + attrs['__mapping__'] = mappings #保留属性和列的映射关系 + attrs['__table__'] = tableName + attrs['__primary_key__'] = primarykey # + attrs['__fields__'] = fields # + # + attrs['__select__'] = 'select `%s`,%s from `%s`' %(primarykey,', '.join(escaped_fields),tableName) + attrs['__insert__'] = 'insert into `%s` (%s, `%s`) values (%s)' %(ableName,', '.join(escaped_fields),primarykey,create_args_string(len(escaped_fields)+1)) + attrs['__update__'] = 'update `%s` set %s where `%s`=?' %(tableName,', '.join(map(lambda f:'`%s`=?' %(mapp`.get(f).name or f),fields)),primarykey) + attrs['__delete__'] = 'delete from `%s` where `%s`=?' %(tableName,primarykey) + return type.__new__(cl,name,bases,attrs) + \ No newline at end of file