94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
from sqlor.filter import DBFilter
|
|
|
|
result = {'success': False, 'rows': [], 'total': 0}
|
|
|
|
try:
|
|
dbname = get_module_dbname('llmage')
|
|
page = int(params_kw.get('page', 1))
|
|
rows_per_page = int(params_kw.get('rows', 20))
|
|
offset = (page - 1) * rows_per_page
|
|
|
|
# Get data_filter JSON from frontend
|
|
filterjson_str = params_kw.get('data_filter')
|
|
filterjson = None
|
|
if filterjson_str:
|
|
try:
|
|
filterjson = json.loads(filterjson_str)
|
|
except (json.JSONDecodeError, TypeError):
|
|
filterjson = None
|
|
|
|
async with DBPools().sqlorContext(dbname) as sor:
|
|
where_clause = ''
|
|
filterdic = {}
|
|
if filterjson:
|
|
# Preprocess LIKE values: add wildcards if user didn't provide them
|
|
ns = dict(params_kw)
|
|
for key, val in ns.items():
|
|
# Check if this var is used with LIKE op in filterjson
|
|
if _is_like_var(filterjson, key) and val and '%' not in val:
|
|
ns[key] = f'%{val}%'
|
|
|
|
dbf = DBFilter(filterjson)
|
|
conds = dbf.gen(ns)
|
|
if conds:
|
|
where_clause = f' WHERE {conds}'
|
|
filterdic = ns
|
|
|
|
# Total count
|
|
count_sql = f"select count(*) as cnt from llm{where_clause}"
|
|
count_rows = await sor.sqlExe(count_sql, filterdic)
|
|
total = count_rows[0]['cnt'] if count_rows else 0
|
|
|
|
# Paginated data - JOIN with organization and upapp to get display names
|
|
# Prefix field references in WHERE clause with table alias 'l.'
|
|
join_where = ''
|
|
if where_clause:
|
|
import re
|
|
conds_text = where_clause.replace(' WHERE ', '', 1)
|
|
# Add l. prefix to field names (name, model, providerid, upappid, status)
|
|
conds_text = re.sub(r'\b(name|model|description|providerid|upappid|status|ownerid)\b', r'l.\1', conds_text)
|
|
join_where = f' WHERE {conds_text}'
|
|
|
|
data_sql = f"""
|
|
select l.id, l.name, l.model, l.description, l.iconid,
|
|
l.upappid, l.providerid, l.ownerid, l.enabled_date,
|
|
l.expired_date, l.min_balance, l.status,
|
|
u.name as upappid_text,
|
|
o.orgname as providerid_text
|
|
from llm l
|
|
left join uapi.upapp u on l.upappid = u.id
|
|
left join rbac.organization o on l.providerid = o.id
|
|
{join_where}
|
|
order by l.model
|
|
limit ${limit}$ offset ${offset}$
|
|
"""
|
|
rows = await sor.sqlExe(data_sql, {**filterdic, 'limit': rows_per_page, 'offset': offset})
|
|
result['rows'] = [dict(r) for r in (rows or [])]
|
|
result['total'] = total
|
|
result['success'] = True
|
|
|
|
except Exception as e:
|
|
result['error'] = str(e)
|
|
|
|
return json.dumps(result, ensure_ascii=False, default=str)
|
|
|
|
|
|
def _is_like_var(filterjson, varname):
|
|
"""Check if a var is used with LIKE operator in the filter tree."""
|
|
if not filterjson:
|
|
return False
|
|
for key, val in filterjson.items():
|
|
if key.upper() in ('AND', 'OR') and isinstance(val, list):
|
|
for item in val:
|
|
if _is_like_var(item, varname):
|
|
return True
|
|
elif key.upper() == 'NOT' and isinstance(val, dict):
|
|
if _is_like_var(val, varname):
|
|
return True
|
|
elif isinstance(val, dict) and val.get('var') == varname:
|
|
if val.get('op', '').upper() == 'LIKE':
|
|
return True
|
|
return False
|