/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.eas.client.model.application; import com.eas.client.MetadataCache; import com.eas.client.SQLUtils; import com.eas.client.SqlCompiledQuery; import com.eas.client.SqlQuery; import com.eas.client.changes.Change; import com.eas.client.changes.Command; import com.eas.client.metadata.JdbcField; import com.eas.client.metadata.Parameter; import com.eas.client.model.visitors.ModelVisitor; import com.eas.client.sqldrivers.SqlDriver; import com.eas.client.sqldrivers.resolvers.TypesResolver; import com.eas.script.ScriptFunction; import com.eas.script.Scripts; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.NamingException; import jdk.nashorn.api.scripting.JSObject; /** * * @author mg */ public class ApplicationDbEntity extends ApplicationEntity<ApplicationDbModel, SqlQuery, ApplicationDbEntity> { public ApplicationDbEntity() { super(); } public ApplicationDbEntity(ApplicationDbModel aModel) { super(aModel); } public ApplicationDbEntity(String aEntityId) { super(aEntityId); } @Override public void accept(ModelVisitor<ApplicationDbEntity, ApplicationDbModel> visitor) { visitor.visit(this); } @ScriptFunction(jsDoc = EXECUTE_UPDATE_JSDOC, params = {"onSuccess", "onFailure"}) @Override public int executeUpdate(JSObject onSuccess, JSObject onFailure) throws Exception { if (onSuccess != null) { model.getBasesProxy().executeUpdate(getQuery().compile(Scripts.getSpace()), (Integer aUpdated) -> { onSuccess.call(null, new Object[]{aUpdated}); }, (Exception ex) -> { if (onFailure != null) { onFailure.call(null, new Object[]{ex.getMessage()}); } }); return 0; } else { return model.getBasesProxy().executeUpdate(getQuery().compile(Scripts.getSpace()), null, null); } } @ScriptFunction(jsDoc = UPDATE_JSDOC, params = {"params", "onSuccess", "onFailure"}) @Override public int update(JSObject aParams, JSObject onSuccess, JSObject onFailure) throws Exception { SqlQuery copied = query.copy(); aParams.keySet().forEach((String pName) -> { Parameter p = copied.getParameters().get(pName); if (p != null) { Object jsValue = aParams.getMember(pName); p.setValue(Scripts.getSpace().toJava(jsValue)); } }); SqlCompiledQuery compiled = copied.compile(); if (onSuccess != null) { model.getBasesProxy().executeUpdate(compiled, (Integer aUpdated) -> { onSuccess.call(null, new Object[]{aUpdated}); }, (Exception ex) -> { if (onFailure != null) { onFailure.call(null, new Object[]{ex.getMessage()}); } }); return 0; } else { return model.getBasesProxy().executeUpdate(compiled, null, null); } } @ScriptFunction(jsDoc = ENQUEUE_UPDATE_JSDOC, params = {"params"}) @Override public void enqueueUpdate(JSObject aParams) throws Exception { SqlQuery copied = query.copy(); if (aParams != null) { aParams.keySet().forEach((String pName) -> { Parameter p = copied.getParameters().get(pName); if (p != null) { Object jsValue = aParams.getMember(pName); // .toJava() call is inside compile(). p.setValue(jsValue); } }); } // WARNING! Don't change copied.compile(Scripts.getSpace()) to copied.compile(). // Not all parameters may be metioned in aParams object, so entity.params will be taken partially. // aParams argument may be omitted, and so, all parameters will be taken from entity.params. SqlCompiledQuery compiled = copied.compile(Scripts.getSpace()); Command command = compiled.prepareCommand(); List<Change> log = getChangeLog(); log.add(command); } @Override public List<Change> getChangeLog() throws Exception { validateQuery(); String datasourceName = tableName != null && !tableName.isEmpty() ? tableDatasourceName : query != null ? query.getDatasourceName() : null; return model.getChangeLog(datasourceName); } @Override public void validateQuery() throws Exception { if (query == null) { if (queryName != null) { SqlQuery q = model.queries.getCachedQuery(queryName); if (q != null) { query = q.copy(); } } else if (tableName != null) { try { query = SQLUtils.validateTableSqlQuery(getTableDatasourceName(), getTableName(), getTableSchemaName(), model.getBasesProxy()); // such resolving is needed here because table queries are not processed by StoredQueryFactory MetadataCache mdCache = model.getBasesProxy().getMetadataCache(query.getDatasourceName()); SqlDriver driver = mdCache.getDatasourceSqlDriver(); TypesResolver resolver = driver.getTypesResolver(); query.getFields().toCollection().stream().forEach((field) -> { field.setType(resolver.toApplicationType(((JdbcField) field).getJdbcType(), field.getType())); }); } catch (Exception ex) { query = null; if (ex instanceof NamingException) { Logger.getLogger(ApplicationDbEntity.class.getName()).log(Level.WARNING, ex.getMessage()); } else { Logger.getLogger(ApplicationDbEntity.class.getName()).log(Level.WARNING, null, ex); } } } else { assert false : "Entity must have queryName or tableName to validate it's query"; } } } }