/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.eas.client.queries;
import com.eas.client.StoredQueryFactory;
import com.eas.client.DatabasesClient;
import com.eas.client.SqlQuery;
import com.eas.client.cache.ActualCacheEntry;
import com.eas.client.cache.PlatypusFiles;
import com.eas.client.cache.PlatypusIndexer;
import com.eas.client.metadata.Field;
import com.eas.client.metadata.Fields;
import com.eas.client.metadata.ForeignKeySpec;
import com.eas.client.metadata.Parameter;
import com.eas.client.metadata.Parameters;
import com.eas.script.Scripts;
import java.io.File;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author mg
*/
public class LocalQueriesProxy implements QueriesProxy<SqlQuery> {
protected Map<String, ActualCacheEntry<SqlQuery>> entries = new ConcurrentHashMap<>();
protected PlatypusIndexer indexer;
protected StoredQueryFactory factory;
protected DatabasesClient core;
public LocalQueriesProxy(DatabasesClient aBasesProxy, PlatypusIndexer aIndexer) throws Exception {
super();
indexer = aIndexer;
factory = new StoredQueryFactory(aBasesProxy, this, indexer);
core = aBasesProxy;
}
@Override
public SqlQuery getQuery(String aName, Scripts.Space aSpace, Consumer<SqlQuery> onSuccess, Consumer<Exception> onFailure) throws Exception {
Callable<SqlQuery> doWork = () -> {
SqlQuery query;
if (aName != null) {
Date cachedTimeStamp = null;
ActualCacheEntry<SqlQuery> entry = entries.get(aName);
if (entry != null) {
cachedTimeStamp = entry.getTimeStamp();
}
File file = indexer.nameToFile(aName);
if (file != null) {
Date filesTimeStamp = new Date(file.lastModified());
if (cachedTimeStamp == null || filesTimeStamp.after(cachedTimeStamp)) {
if (file.getName().endsWith(PlatypusFiles.SQL_FILE_END)) {
query = factory.loadQuery(aName);
} else {
String nameMsg;
if (aName.isEmpty()) {
nameMsg = "empty string name";
} else {
nameMsg = "name '" + aName + "'";
}
throw new IllegalStateException("Query with " + nameMsg + " can't be constructed. Queries can be constructed with only platypus queries application elements.");
}
entries.put(aName, new ActualCacheEntry<>(query, filesTimeStamp));
} else {
assert entry != null : "Neither in memory, nor in files query found";
query = entry.getValue();
}
} else// Let's support in memory only (without underlying files) queries. Used in createEntity().
{
if (entry != null) {
query = entry.getValue();
} else {
query = null;
}
}
} else {
query = null;
}
return query;
};
if (onSuccess != null) {
aSpace.process(() -> {
try {
SqlQuery query = doWork.call();
try {
onSuccess.accept(query);
} catch (Exception ex) {
Logger.getLogger(LocalQueriesProxy.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (Exception ex) {
if (onFailure != null) {
onFailure.accept(ex);
}
}
});
return null;
} else {
return doWork.call();
}
}
/*
private void readScriptFields(String aQueryName, JSObject sSchema, Fields fields, Scripts.Space aSpace) {
Object oLength = sSchema.getMember("length");
if (oLength instanceof Number) {
int length = ((Number) oLength).intValue();
for (int i = 0; i < length; i++) {
Object oElement = sSchema.getSlot(i);
if (oElement instanceof JSObject) {
JSObject sElement = (JSObject) oElement;
Object oFieldName = aSpace.toJava(sElement.hasMember("name") ? sElement.getMember("name") : null);
if (oFieldName instanceof String && !((String) oFieldName).isEmpty()) {
String sFieldName = (String) oFieldName;
Field field = fields instanceof Parameters ? new Parameter() : new Field();
field.setType(Scripts.STRING_TYPE_NAME);
fields.add(field);
field.setName(sFieldName);
field.setOriginalName(sFieldName);
Object oEntity = aSpace.toJava(sElement.hasMember("entity") ? sElement.getMember("entity") : null);
if (oEntity instanceof String && !((String) oEntity).isEmpty()) {
field.setTableName((String) oEntity);
} else {
field.setTableName(aQueryName);
}
Object oDescription = aSpace.toJava(sElement.hasMember("description") ? sElement.getMember("description") : null);
if (oDescription instanceof String && !((String) oDescription).isEmpty()) {
field.setDescription((String) oDescription);
}
Object oType = sElement.getMember("type");
if (oType instanceof JSObject && ((JSObject) oType).isFunction()) {
Object ofName = aSpace.toJava(((JSObject) oType).getMember("name"));
if (ofName instanceof String) {
String fName = (String) ofName;
if (Scripts.STRING_TYPE_NAME.equals(fName)) {
field.setType(Scripts.STRING_TYPE_NAME);
} else if (Scripts.NUMBER_TYPE_NAME.equals(fName)) {
field.setType(Scripts.NUMBER_TYPE_NAME);
} else if (Scripts.BOOLEAN_TYPE_NAME.equals(fName)) {
field.setType(Scripts.BOOLEAN_TYPE_NAME);
} else if (Scripts.DATE_TYPE_NAME.equals(fName)) {
field.setType(Scripts.DATE_TYPE_NAME);
} else if (Scripts.GEOMETRY_TYPE_NAME.equals(fName)) {
field.setType(Scripts.GEOMETRY_TYPE_NAME);
}
}
}
Object oRequired = aSpace.toJava(sElement.hasMember("required") ? sElement.getMember("required") : null);
if (oRequired instanceof Boolean) {
boolean bRequired = (Boolean) oRequired;
field.setNullable(!bRequired);
}
Object oKey = aSpace.toJava(sElement.hasMember("key") ? sElement.getMember("key") : null);
if (oKey instanceof Boolean) {
boolean bKey = (Boolean) oKey;
field.setPk(bKey);
field.setNullable(false);
}
Object oRef = sElement.hasMember("ref") ? sElement.getMember("ref") : null;
if (oRef instanceof JSObject) {
JSObject sRef = (JSObject) oRef;
Object oProperty = aSpace.toJava(sRef.hasMember("property") ? sRef.getMember("property") : null);
if (oProperty instanceof String) {
String sProperty = (String) oProperty;
if (!sProperty.isEmpty()) {
Object oRefEntity = sRef.hasMember("entity") ? sRef.getMember("entity") : null;
String sRefEntity;
if (oRefEntity instanceof String && !((String) oRefEntity).isEmpty()) {
sRefEntity = (String) oRefEntity;
} else {
sRefEntity = aQueryName;
}
field.setFk(new ForeignKeySpec(null, aQueryName, field.getName(), null, ForeignKeySpec.ForeignKeyRule.CASCADE, ForeignKeySpec.ForeignKeyRule.CASCADE, false, null, sRefEntity, sProperty, null));
}
}
}
}
}
}
}
}
*/
@Override
public SqlQuery getCachedQuery(String aName) {
if (aName != null) {
ActualCacheEntry<SqlQuery> entry = entries.get(aName);
if (entry != null) {
return entry.getValue();
} else {
return null;
}
} else {
return null;
}
}
public void putCachedQuery(String aName, SqlQuery aQuery) {
entries.put(aName, new ActualCacheEntry<>(aQuery, new Date()));
}
public DatabasesClient getCore() {
return core;
}
public void clearCachedQueries() {
entries.clear();
}
public void clearCachedQuery(String aQueryName) {
if (aQueryName != null) {
entries.remove(aQueryName);
}
}
}