bugfix
This commit is contained in:
parent
62514a2398
commit
f89b972576
373
sqlor/crud.py
373
sqlor/crud.py
@ -1,373 +0,0 @@
|
|||||||
# -*- coding:utf8 -*-
|
|
||||||
from .dbpools import DBPools
|
|
||||||
from .const import ROWS
|
|
||||||
from .filter import DBFilter
|
|
||||||
from appPublic.objectAction import ObjectAction
|
|
||||||
from appPublic.dictObject import DictObject
|
|
||||||
from appPublic.timeUtils import date2str,time2str,str2Date
|
|
||||||
from appPublic.uniqueID import getID
|
|
||||||
toStringFuncs={
|
|
||||||
'char':None,
|
|
||||||
'str':None,
|
|
||||||
'short':str,
|
|
||||||
'long':str,
|
|
||||||
'float':str,
|
|
||||||
'date':date2str,
|
|
||||||
'time':time2str,
|
|
||||||
}
|
|
||||||
fromStringFuncs={
|
|
||||||
'short':int,
|
|
||||||
'long':int,
|
|
||||||
'float':float,
|
|
||||||
'date':str2Date,
|
|
||||||
'time':str2Date
|
|
||||||
}
|
|
||||||
|
|
||||||
class DatabaseNotfound(Exception):
|
|
||||||
def __init__(self,dbname):
|
|
||||||
Exception.__init__(self)
|
|
||||||
self.dbname = dbname
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f'{self.dbname} not found'
|
|
||||||
|
|
||||||
class CRUD(object):
|
|
||||||
def __init__(self,dbname,tablename,rows=ROWS):
|
|
||||||
self.pool = DBPools()
|
|
||||||
if dbname not in self.pool.databases.keys():
|
|
||||||
raise DatabaseNotfound(dbname)
|
|
||||||
self.dbname = dbname
|
|
||||||
self.tablename = tablename
|
|
||||||
self.rows = rows
|
|
||||||
self.primary_data = None
|
|
||||||
self.oa = ObjectAction()
|
|
||||||
|
|
||||||
async def primaryKey(self,**kw):
|
|
||||||
if self.primary_data is None:
|
|
||||||
self.primary_data = await self.pool.getTablePrimaryKey(self.dbname,
|
|
||||||
self.tablename,**kw)
|
|
||||||
|
|
||||||
return self.primary_data
|
|
||||||
|
|
||||||
async def forignKeys(self,**kw):
|
|
||||||
data = self.pool.getTableForignKeys(self.dbname,self.tablename,**kw)
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def I(self,**kw):
|
|
||||||
"""
|
|
||||||
fields information
|
|
||||||
"""
|
|
||||||
@self.pool.inSqlor
|
|
||||||
async def main(dbname,NS,**kw):
|
|
||||||
pkdata = await self.primaryKey(**kw)
|
|
||||||
pks = [ i.field_name for i in pkdata ]
|
|
||||||
data = await self.pool.getTableFields(self.dbname,self.tablename,**kw)
|
|
||||||
for d in data:
|
|
||||||
if d.name in pks:
|
|
||||||
d.update({'primarykey':True})
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'tableInfo',data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
return await main(self.dbname,{},**kw)
|
|
||||||
|
|
||||||
async def fromStr(self,data):
|
|
||||||
fields = await self.pool.getTableFields(self.dbname,self.tablename)
|
|
||||||
ret = {}
|
|
||||||
for k in data:
|
|
||||||
v = None if data[k] == '' else data[k]
|
|
||||||
for f in fields:
|
|
||||||
if k == f.name:
|
|
||||||
ret[k] = v
|
|
||||||
f = fromStringFuncs.get(f.type,None)
|
|
||||||
if f is not None and v is not None:
|
|
||||||
ret[k] = f(v)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
async def toStr(self,data):
|
|
||||||
fields = await self.pool.getTableFields(self.dbname,self.tablename)
|
|
||||||
ret = {}
|
|
||||||
for k in data:
|
|
||||||
for f in fields:
|
|
||||||
if k == f.name:
|
|
||||||
ret[k] = data[k]
|
|
||||||
f = toStringFuncs.get(f.type,None)
|
|
||||||
if f is not None and data[k] is not None:
|
|
||||||
ret[k] = f(data[k])
|
|
||||||
return ret
|
|
||||||
|
|
||||||
async def datagrid(self,request,targeti,**kw):
|
|
||||||
fields = await self.I()
|
|
||||||
fs = [ self.defaultIOField(f) for f in fields ]
|
|
||||||
id = self.dbname+':'+ self.tablename
|
|
||||||
pk = await self.primaryKey(**kw)
|
|
||||||
idField = pk[0]['field_name']
|
|
||||||
data = {
|
|
||||||
"tmplname":"widget_js.tmpl",
|
|
||||||
"data":{
|
|
||||||
"__ctmpl__":"datagrid",
|
|
||||||
"__target__":target,
|
|
||||||
"data":{
|
|
||||||
"name":id,
|
|
||||||
"icon-conv":"icon-table",
|
|
||||||
"title":tablename,
|
|
||||||
"url":absurl('./RP.dspy?id=%s' % id),
|
|
||||||
"deleteUrl":absurl('./D.dspy?id=%s' % id),
|
|
||||||
"addUrl":absurl('./C.dspy?id=%s' % id),
|
|
||||||
"updateUrl":absurl('./U.dspy?id=%s' % id),
|
|
||||||
"idField":idField,
|
|
||||||
"dnd":True,
|
|
||||||
"view":"scrollview",
|
|
||||||
"fields":fs,
|
|
||||||
"toolbar":{
|
|
||||||
"tools":[
|
|
||||||
{
|
|
||||||
"name":"add",
|
|
||||||
"icon":"icon-add",
|
|
||||||
"label":"add ball"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"delete",
|
|
||||||
"icon":"icon-delete",
|
|
||||||
"label":"delete ball"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"moveup",
|
|
||||||
"icon":"icon-up",
|
|
||||||
"label":"moveup ball"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"movedown",
|
|
||||||
"icon":"icon-down",
|
|
||||||
"label":"movedown ball"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"options":{
|
|
||||||
"pageSize":50,
|
|
||||||
"pagination":False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data = self.oa.execute(id,'datagrid',data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def defaultIOField(self,f):
|
|
||||||
if f.type in ['str']:
|
|
||||||
return {
|
|
||||||
"primarykey":f.get('primarykey',False),
|
|
||||||
"name":f.name,
|
|
||||||
"hidden":False,
|
|
||||||
"sortable":True,
|
|
||||||
"label":f.title,
|
|
||||||
"align":"center",
|
|
||||||
"iotype":"text"
|
|
||||||
}
|
|
||||||
if f.type in ['float','short','long']:
|
|
||||||
return {
|
|
||||||
"primarykey":f.get('primarykey',False),
|
|
||||||
"sortable":True,
|
|
||||||
"name":f.name,
|
|
||||||
"hidden":False,
|
|
||||||
"label":f.title,
|
|
||||||
"align":"right",
|
|
||||||
"iotype":"text"
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
"primarykey":f.get('primarykey',False),
|
|
||||||
"name":f.name,
|
|
||||||
"sortable":True,
|
|
||||||
"hidden":False,
|
|
||||||
"label":f.title,
|
|
||||||
"align":"center",
|
|
||||||
"iotype":"text"
|
|
||||||
}
|
|
||||||
|
|
||||||
async def C(self,rec,**kw):
|
|
||||||
"""
|
|
||||||
create new data
|
|
||||||
"""
|
|
||||||
@self.pool.runSQL
|
|
||||||
async def addSQL(dbname,data,**kw):
|
|
||||||
fns = kw['fns']
|
|
||||||
vfs = kw['vfs']
|
|
||||||
sqldesc={
|
|
||||||
"sql_string" : """
|
|
||||||
insert into %s (%s) values (%s)
|
|
||||||
""" % (self.tablename,fns,vfs),
|
|
||||||
}
|
|
||||||
return sqldesc
|
|
||||||
|
|
||||||
@self.pool.inSqlor
|
|
||||||
async def main(dbname,NS,**kw):
|
|
||||||
fields = await self.pool.getTableFields(self.dbname,self.tablename,**kw)
|
|
||||||
flist = [ f['name'] for f in fields ]
|
|
||||||
fns = ','.join(flist)
|
|
||||||
vfs = ','.join([ '${' + f + '}$' for f in flist ])
|
|
||||||
data = {}
|
|
||||||
[ data.update({k.lower():v}) for k,v in NS.items() ]
|
|
||||||
pk = await self.primaryKey(**kw)
|
|
||||||
k = pk[0]['field_name']
|
|
||||||
if not data.get(k):
|
|
||||||
v = getID()
|
|
||||||
data[k] = v
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'beforeAdd',data)
|
|
||||||
kwargs = kw.copy()
|
|
||||||
kwargs['fns'] = fns
|
|
||||||
kwargs['vfs'] = vfs
|
|
||||||
await addSQL(self.dbname,data,**kwargs)
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'afterAdd',data)
|
|
||||||
return {k:data[k]}
|
|
||||||
|
|
||||||
return await main(self.dbname,rec,**kw)
|
|
||||||
|
|
||||||
async def defaultFilter(self,NS,**kw):
|
|
||||||
fields = await self.pool.getTableFields(self.dbname,self.tablename,**kw)
|
|
||||||
d = [ '%s = ${%s}$' % (f['name'],f['name']) for f in fields if f['name'] in NS.keys() ]
|
|
||||||
if len(d) == 0:
|
|
||||||
return ''
|
|
||||||
ret = ' and ' + ' and '.join(d)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
async def R(self,filters=None,NS={},**kw):
|
|
||||||
"""
|
|
||||||
retrieve data
|
|
||||||
"""
|
|
||||||
@self.pool.runSQL
|
|
||||||
async def retrieve(dbname,data,**kw):
|
|
||||||
fstr = ''
|
|
||||||
if filters is not None:
|
|
||||||
fstr = ' and '
|
|
||||||
dbf = DBFilter(filters)
|
|
||||||
fstr = fstr + dbf.genFilterString()
|
|
||||||
else:
|
|
||||||
fstr = await self.defaultFilter(NS,**kw)
|
|
||||||
sqldesc = {
|
|
||||||
"sql_string":"""select * from %s where 1=1 %s""" % (self.tablename,fstr),
|
|
||||||
}
|
|
||||||
return sqldesc
|
|
||||||
|
|
||||||
@self.pool.runSQLPaging
|
|
||||||
async def pagingdata(dbname,data,filters=None,**kw):
|
|
||||||
fstr = ""
|
|
||||||
if filters is not None:
|
|
||||||
fstr = ' and '
|
|
||||||
dbf = DBFilter(filters)
|
|
||||||
fstr = fstr + dbf.genFilterString()
|
|
||||||
else:
|
|
||||||
fstr = await self.defaultFilter(NS,**kw)
|
|
||||||
|
|
||||||
sqldesc = {
|
|
||||||
"sql_string":"""select * from %s where 1=1 %s""" % (self.tablename,fstr),
|
|
||||||
"default":{'rows':self.rows}
|
|
||||||
}
|
|
||||||
return sqldesc
|
|
||||||
|
|
||||||
@self.pool.inSqlor
|
|
||||||
async def main(dbname,NS,**kw):
|
|
||||||
p = await self.primaryKey(**kw)
|
|
||||||
if NS.get('__id') is not None:
|
|
||||||
NS[p[0]['field_name']] = NS['__id']
|
|
||||||
del NS['__id']
|
|
||||||
if NS.get('page'):
|
|
||||||
del NS['page']
|
|
||||||
|
|
||||||
if NS.get('page'):
|
|
||||||
if NS.get('sort',None) is None:
|
|
||||||
NS['sort'] = p[0]['field_name']
|
|
||||||
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'beforeRetrieve',NS)
|
|
||||||
if NS.get('page'):
|
|
||||||
data = await pagingdata(self.dbname,data,**kw)
|
|
||||||
else:
|
|
||||||
data = await retrieve(self.dbname,data,**kw)
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'afterRetrieve',data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
return await main(self.dbname,NS,**kw)
|
|
||||||
|
|
||||||
async def U(self,data, **kw):
|
|
||||||
"""
|
|
||||||
update data
|
|
||||||
"""
|
|
||||||
@self.pool.runSQL
|
|
||||||
async def update(dbname,NS,**kw):
|
|
||||||
condi = [ i['field_name'] for i in self.primary_data ]
|
|
||||||
newData = [ i for i in NS.keys() if i not in condi ]
|
|
||||||
c = [ '%s = ${%s}$' % (i,i) for i in condi ]
|
|
||||||
u = [ '%s = ${%s}$' % (i,i) for i in newData ]
|
|
||||||
cs = ' and '.join(c)
|
|
||||||
us = ','.join(u)
|
|
||||||
sqldesc = {
|
|
||||||
"sql_string":"""update %s set %s where %s""" % (self.tablename,us,cs)
|
|
||||||
}
|
|
||||||
return sqldesc
|
|
||||||
|
|
||||||
@self.pool.inSqlor
|
|
||||||
async def main(dbname,NS,**kw):
|
|
||||||
pk = await self.primaryKey(**kw)
|
|
||||||
pkfields = [k.field_name for k in pk ]
|
|
||||||
newData = [ k for k in data if k not in pkfields ]
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'beforeUpdate',data)
|
|
||||||
await update(self.dbname,data,**kw)
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'afterUpdate',data)
|
|
||||||
return data
|
|
||||||
return await main(self.dbname,data,**kw)
|
|
||||||
|
|
||||||
async def D(self,data,**kw):
|
|
||||||
"""
|
|
||||||
delete data
|
|
||||||
"""
|
|
||||||
@self.pool.runSQL
|
|
||||||
def delete(dbname,data,**kw):
|
|
||||||
pnames = [ i['field_name'] for i in self.primary_data ]
|
|
||||||
c = [ '%s = ${%s}$' % (i,i) for i in pnames ]
|
|
||||||
cs = ' and '.join(c)
|
|
||||||
sqldesc = {
|
|
||||||
"sql_string":"delete from %s where %s" % (self.tablename,cs)
|
|
||||||
}
|
|
||||||
return sqldesc
|
|
||||||
|
|
||||||
@self.pool.inSqlor
|
|
||||||
async def main(dbname,NS,**kw):
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'beforeDelete',data)
|
|
||||||
await delete(self.dbname,data,pkfields,**kw)
|
|
||||||
data = self.oa.execute(self.dbname+'_'+self.tablename,'afterDelete',data)
|
|
||||||
return data
|
|
||||||
return await main(self.dbname,data,**kw)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
DBPools({
|
|
||||||
"ambi":{
|
|
||||||
"driver":"pymssql",
|
|
||||||
"coding":"utf-8",
|
|
||||||
"dbname":"ambi",
|
|
||||||
"kwargs":{
|
|
||||||
"user":"ymq",
|
|
||||||
"database":"ambi",
|
|
||||||
"password":"ymq123",
|
|
||||||
"host":"localhost"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadb":{
|
|
||||||
"driver":"pymssql",
|
|
||||||
"coding":"utf-8",
|
|
||||||
"dbname":"metadb",
|
|
||||||
"kwargs":{
|
|
||||||
"user":"ymq",
|
|
||||||
"database":"metadb",
|
|
||||||
"password":"ymq123",
|
|
||||||
"host":"localhost"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
crud = CRUD('ambi')
|
|
||||||
#fields = crud.I('cashflow')
|
|
||||||
#for i in fields:
|
|
||||||
# print(i)
|
|
||||||
|
|
||||||
data = crud.RP('cashflow')
|
|
||||||
print(data.total)
|
|
||||||
for i in data.rows:
|
|
||||||
print(i.balance,i.asid)
|
|
||||||
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
import sys
|
|
||||||
import codecs
|
|
||||||
from sqlor.dbpools import runSQL
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
def appinit():
|
|
||||||
if len(sys.argv) < 4:
|
|
||||||
print(f'usage:\n {sys.argv[0]} path dbname sqlfile [k=v ...] \n')
|
|
||||||
sys.exit(1)
|
|
||||||
p = ProgramPath()
|
|
||||||
if len(sys.argv) > 1:
|
|
||||||
p = sys.argv[1]
|
|
||||||
config = getConfig(p)
|
|
||||||
DBPools(config.databases)
|
|
||||||
|
|
||||||
|
|
||||||
async def run(ns):
|
|
||||||
with codecs.open(sys.argv[3], 'r', 'utf-8') as f:
|
|
||||||
sql = f.read()
|
|
||||||
await runSQL(sys.argv[2], sql, ns)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
ns = {}
|
|
||||||
for x in sys.argv[3:]:
|
|
||||||
try:
|
|
||||||
k,v = x.split('=')
|
|
||||||
ns.update({k:v})
|
|
||||||
except Exception as e:
|
|
||||||
print(x, 'key-value pair expected')
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
appinit()
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
loop.run_until_complete(run(ns))
|
|
||||||
Loading…
x
Reference in New Issue
Block a user