import { DBModule, DBTable, MapData, ModuleInstruction, loadLanguageModule, parseXML } from "@cyklang/core" import loglevel from 'loglevel' import { useCykStore } from "./cykStore" import { dbRemote, getDBManager, structure, verifyAccessRight } from "./cykLang" import { AlertException } from "./cykRun" const logger = loglevel.getLogger('adminTable') logger.setLevel('debug') /** * * @param tableName */ export async function generateTableCRUD(tableName: string, browserLanguage?: string | undefined) { try { const store = useCykStore() if (!store.user.logged) { await store.currentuser() if (!store.user.logged) { // store.loginRoute = route.path window.location.hash = '/login' } } const dbManager = await getDBManager() const dbTable = await dbManager.dbTableExist(tableName) if (!dbTable) { throw 'table ' + tableName + ' not found' } logger.debug(`generateTableCRUD browserLanguage=${browserLanguage}, dbTable.packageName=${dbTable.packageName}`) await loadLanguageModule(structure.scope, dbManager, dbTable.packageName || '', [store.user.user_lang, browserLanguage, 'en-US']) const source_code = await admin_table_generate(dbTable) store.module.source_edit = source_code // logger.debug('generated_code: ', source_code) } catch (err) { alert(String(err)) } } const LS_SELECT_OPTIONS_LIMIT = 'cyk:SELECT-OPTIONS-LIMIT' const item_select_options_limit = localStorage.getItem(LS_SELECT_OPTIONS_LIMIT) const SELECT_OPTIONS_LIMIT = Number(item_select_options_limit) || 100 if (!item_select_options_limit) { localStorage.setItem(LS_SELECT_OPTIONS_LIMIT, String(SELECT_OPTIONS_LIMIT)) } /** * * @param dbTable * @returns */ async function scan_columns(dbTable: DBTable): Promise<{ fields: string, template: string, order_by: string, columns: string }> { let template = '' let fields = '' let columns = '' const dbColumns = dbTable.objectDataType?.dbColumns if (!dbColumns) throw 'dbColumns undefined' const order_by = dbColumns.primaryColumns.map((value) => value.name).join(',') for (let ind = 0; ind < dbColumns.columns.length; ind++) { const dbColumn = dbColumns.columns[ind] if (dbColumn.name.endsWith('__meta')) continue if (dbColumn.dbType === 'bytea') continue if (dbColumn.computed) continue let component = dbColumn.component if (dbColumn.parentTable) { const { count } = await (await getDBManager()).dcount('*', dbColumn.parentTable) logger.debug(`dcount('*', ${dbColumn.parentTable} ) = ${count}`) if (count < SELECT_OPTIONS_LIMIT) component = 'select' } if (!component) { component = 'input' } let label = dbColumn.label || dbColumn.name let readonly = '' if (dbColumn.dbPrimary && dbColumn.dbGenerated) { readonly = " readonly='true' " } // let computed = '' // if (dbColumn.computed) { // const escaped = dbColumn.computed.replace(/'/g, "'") // computed = ` computed='${escaped}' ` // } let tag if (component === 'select' && dbColumn.parentTable) { tag = ` ` } else if (component === 'checkbox') { tag = ` ` } else if (component === 'qimg') { // const field_name = dbColumn.name.substring(0, dbColumn.name.length - 5) // template = 'expand' // if (dbColumns.primaryColumns.length > 1) throw 'qimg more than 1 primary column unsupported' if (dbColumns.primaryColumns.length === 0) throw 'qimg no primary column is unsupported' tag = ` "${dbTable.name}" "${field_name}" temp.dbkey() ` } else if (component === 'file') { // const field_name = dbColumn.name.substring(0, dbColumn.name.length - 5) if (dbColumns.primaryColumns.length === 0) throw 'file no primary column is unsupported' tag = ` "${dbTable.name}" "${field_name}" temp.dbkey() ` logger.debug(`component file: ${tag}`) } fields += tag if (columns !== '') columns += ',' columns += dbColumn.name } return { fields, template, order_by, columns } } /** * * @param dbTable */ function scan_primary_columns(dbTable: DBTable) { let pkey_params_dcl = '' let pkey_equals = '' let pkey_params_val = '' const primaryColumns = dbTable.objectDataType?.dbColumns?.primaryColumns if (!primaryColumns) throw 'dbTable has no primary column: ' + dbTable.name for (let ind = 0; ind < primaryColumns.length; ind++) { const primaryColumn = primaryColumns[ind] if (ind > 0) pkey_equals += ' AND ' pkey_equals += `${primaryColumn.name} = {{ ${primaryColumn.name}}}` pkey_params_dcl += `<${primaryColumn.dataTypeName} name="${primaryColumn.name}" />` pkey_params_val += `<${primaryColumn.dataTypeName} name="${primaryColumn.name}">${dbTable.name}.${primaryColumn.name}` } return { pkey_params_dcl, pkey_equals, pkey_params_val } } const LS_QUERY_LIMIT = 'cyk:QUERY-LIMIT' const item = localStorage.getItem(LS_QUERY_LIMIT) const QUERY_LIMIT = Number(item) || 1000 if (!item) { localStorage.setItem(LS_QUERY_LIMIT, String(QUERY_LIMIT)) } /** * * @param dbTable * @returns */ export async function admin_table_generate(dbTable: DBTable): Promise { try { const tableName = dbTable.name if (dbTable.objectDataType?.dbColumns?.primaryColumns.length === 0) throw 'table has no primary key: ' + dbTable.name const primaryColumnName = dbTable.objectDataType?.dbColumns?.primaryColumns[0].name const { fields, template, order_by, columns } = await scan_columns(dbTable) const { pkey_params_dcl, pkey_equals, pkey_params_val } = scan_primary_columns(dbTable) let buttonHistory = '' if (dbTable.log) { buttonHistory = ` ` } let result = ` ${tableName}.copy() ${fields}