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