
com.caucho.v5.ramp.vault.VaultDriverDataImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of baratine Show documentation
Show all versions of baratine Show documentation
A reactive Java web server.
/*
* Copyright (c) 1998-2015 Caucho Technology -- all rights reserved
*
* This file is part of Baratine(TM)
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Baratine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Baratine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Baratine; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Alex Rojkov
*/
package com.caucho.v5.ramp.vault;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import com.caucho.v5.amp.ServicesAmp;
import com.caucho.v5.amp.ServiceRefAmp;
import com.caucho.v5.amp.vault.MethodVault;
import com.caucho.v5.amp.vault.VaultDriver;
import com.caucho.v5.amp.vault.VaultDriverBase;
import com.caucho.v5.amp.vault.VaultStore;
import com.caucho.v5.kraken.info.TableInfo;
import com.caucho.v5.util.L10N;
import io.baratine.db.Cursor;
import io.baratine.db.DatabaseServiceSync;
import io.baratine.service.Result;
import io.baratine.service.ServiceException;
import io.baratine.service.ServiceRef;
import io.baratine.stream.ResultStream;
import io.baratine.vault.Asset;
import io.baratine.vault.IdAsset;
public class VaultDriverDataImpl
extends VaultDriverBase
implements VaultDriver, VaultStore
{
private static final L10N L = new L10N(VaultDriverDataImpl.class);
private static final Logger log
= Logger.getLogger(VaultDriverDataImpl.class.getName());
private final static Map,String> _typeMap = new HashMap<>();
private Class _idClass;
private Class _entityClass;
private EntityInfo _entityInfo;
private DatabaseServiceSync _db;
@Inject
private TableManagerVault _schemaManager;
private String _saveSql;
private String _loadSql;
private IdReader _idReader;
private ServicesAmp _ampManager;
private TableInfo _tableInfo;
public VaultDriverDataImpl(ServicesAmp ampManager,
Class entityClass,
Class idClass,
String address)
{
super(ampManager, entityClass, idClass, address);
Objects.requireNonNull(entityClass);
Objects.requireNonNull(idClass);
_entityClass = entityClass;
_idClass = idClass;
_ampManager = ServicesAmp.current();
_db = _ampManager.service("bardb:///")
.as(DatabaseServiceSync.class);
Objects.requireNonNull(_db);
introspect();
}
private void introspect()
{
Asset table = _entityClass.getAnnotation(Asset.class);
_entityInfo = new EntityInfo<>(_entityClass, _idClass, table);
TableManagerVault schemaManager = new TableManagerVault<>(_db, _entityInfo);
_tableInfo = schemaManager.initializeSchema();
_entityInfo.fillColumns(_tableInfo);
/*
(b, e) -> {
if (e instanceof RuntimeException)
throw (RuntimeException) e;
else if (e != null)
throw new RuntimeException(e);
else if (!b) createTable();
});
*/
_saveSql = _entityInfo.saveSql();
_loadSql = _entityInfo.loadSql();
}
EntityInfo entityInfo()
{
return _entityInfo;
}
@Override
public boolean isPersistent()
{
return true;
}
@Override
public void load(ID id, T entity, Result result)
{
if (log.isLoggable(Level.FINER)) {
log.finer(L.l("loading entity {0} for id {1}",
_entityInfo,
id));
}
if (_entityInfo.isSolo()) {
id = (ID) new Integer(1);
}
_db.findOne(_loadSql,
result.of(c -> onLoad(c, entity)),
_entityInfo.id().toParam(id));
}
/**
* Fills the entity on load complete.
*/
private boolean onLoad(Cursor cursor, T entity)
{
if (cursor == null) {
if (log.isLoggable(Level.FINEST)) {
log.finest(L.l("{0} cursor is null", _entityInfo));
}
return false;
}
else {
try {
// T t = _entityDesc.readObject(c, false);
_entityInfo.load(cursor, entity);
// _entityDesc.setPk(t, id);
if (log.isLoggable(Level.FINER)) {
log.finer("loaded " + entity);
}
return true;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
//TODO log.log()
throw ServiceException.createAndRethrow(e);
}
}
}
@Override
public void save(ID id, T entity, Result result)
{
if (log.isLoggable(Level.FINER)) {
log.finer("saving entity " + entity);
}
Object[] values = _entityInfo.saveValues(entity);
_db.exec(_saveSql, result.of(o -> { return null; }), values);
}
@Override
public void findOne(String[] fields, Object[] values, Result result)
{
String sql = getSelectPkSql(fields);
_db.findOne(sql, result.of(c -> readIdFromCursor(c)), values);
}
@Override
public void findOneCursor(String sql,
Object[] values,
Result result)
{
_db.findOne(sql, result, values);
}
@Override
public void findCursor(String sql,
Object[] values,
Result> result)
{
_db.findAll(sql, result, values);
}
public void findOne(String where, Object[] values, Result result)
{
String sql = getSelectPkSql(where);
_db.findOne(sql, result.of(c -> readIdFromCursor(c)), values);
}
@Override
public void findValue(String sql, Object[] values, Result result)
{
_db.findOne(sql,
result.of(c -> c == null ? null : (X) c.getObject(1)),
values);
}
@Override
public void findAllIds(String where, Object[] values, Result> result)
{
String sql = getSelectPkSql(where);
_db.findAll(sql, result.of(iter -> readIdListFromCursor(iter)), values);
}
@Override
public void findValueList(String sql,
Object[] values,
Result> result)
{
Iterable rows = _db.findAll(sql, values);
List list = new ArrayList<>();
for (Cursor row : rows) {
list.add((X) row.getObject(1));
}
result.ok(list);
}
@Override
public T toProxy(Object id)
{
if (id == null) {
return null;
}
ServiceRef ref = _ampManager.service(toAddress(id));
return ref.as(_entityClass);
}
@Override
public ServiceRefAmp lookup(ID id)
{
if (id == null) {
return null;
}
ServiceRefAmp ref = (ServiceRefAmp) _ampManager.service(toAddress(id));
return ref;
}
private String toAddress(Object id)
{
if (id == null) {
return null;
}
else if (id instanceof Long) {
return getAddress() + '/' + IdAsset.encode((Long) id);
}
else {
return getAddress() + '/' + id;
}
}
@Override
public void findAllIds(ResultStream ids)
{
String sql = getSelectIds();
_db.findAll(sql, ids.of((i, r) -> relayIds(i, r)));
}
public List findIdsList()
{
String sql = getSelectIds();
Iterable cursor = _db.findAll(sql);
List list = new ArrayList<>();
for (Cursor id : cursor) {
list.add(readIdFromCursor(id));
}
return list;
}
public List readIdListFromCursor(Iterable cursor)
{
List list = new ArrayList<>();
for (Cursor id : cursor) {
list.add(readIdFromCursor(id));
}
return list;
}
private void relayIds(Iterable from, ResultStream to)
{
try {
for (Cursor c : from) {
ID id = readIdFromCursor(c);
to.accept(id);
}
to.ok();
} catch (Throwable t) {
to.fail(t);
//t.printStackTrace();
}
}
private ID readIdFromCursor(Cursor c)
{
return getIdReader().read(c);
}
private IdReader getIdReader()
{
if (_idReader != null)
return _idReader;
Class idType = _entityInfo.id().getJavaType();
if (isInteger(idType)) {
_idReader = (IdReader) new IntIdReader();
}
else if (long.class == idType || Long.class == idType) {
_idReader = (IdReader) new LongIdReader();
}
else if (IdAsset.class == idType) {
_idReader = (IdReader) new IdAssetReader();
}
else if (String.class == idType) {
_idReader = (IdReader) new StringIdReader();
}
else {
throw new IllegalStateException(String.valueOf(idType));
}
return _idReader;
}
private boolean isInteger(Class t)
{
return int.class == t
|| Integer.class == t
|| byte.class == t
|| Byte.class == t
|| short.class == t
|| Short.class == t;
}
@Override
public void create(T bean, Result result)
{
try {
_entityInfo.nextId(bean);
result.ok(bean);
} catch (Throwable e) {
result.fail(e);
}
}
@Override
public T service(ID id)
{
String address = _entityInfo.generateAddress(id);
return _ampManager.service(address).as(_entityClass);
}
/**
* @param columns
* @param values
* @param stream
*/
public void findMatch(String[] columns,
Object[] values,
ResultStream stream)
{
if (columns.length != values.length)
throw new IllegalArgumentException();
StringBuilder sql = getWildSelect();
sql.append(" where ");
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
sql.append(column).append("=?");
if ((i + 1) < columns.length)
sql.append(" and ");
}
_db.findAll(sql.toString(),
stream.of((i, r) -> readObjects(i, r)),
values);
}
private void readObjects(Iterable it, ResultStream r)
{
try {
for (Cursor cursor : it) {
T bean = _entityInfo.readObject(cursor, true);
r.accept(bean);
}
r.ok();
} catch (ReflectiveOperationException e) {
//TODO log
r.fail(e);
}
}
public void find(Iterable ids, ResultStream stream)
{
//TODO
}
public void findAll(ResultStream stream)
{
StringBuilder sql = getWildSelect();
_db.findAll(sql.toString(), stream.of(this::readObjects));
}
private TableInfo createTable()
{
String tableInfoSql = "show tableinfo " + _entityInfo.tableName();
try {
TableInfo tableInfo = (TableInfo) _db.exec(tableInfoSql);
if (tableInfo != null) {
return tableInfo;
}
} catch (Exception e) {
log.log(Level.FINEST, e.toString(), e);
}
StringBuilder sb = new StringBuilder();
sb.append("create table " + _entityInfo.tableName() + " (");
sb.append("id " + _entityInfo.id().sqlType() + " primary key");
sb.append(", __id");
sb.append(")");
String sqlCreate = sb.toString();
_db.exec(sqlCreate);
return (TableInfo) _db.exec(tableInfoSql);
}
public String getSelectPkSql(String[] where)
{
StringBuilder sql = new StringBuilder("select ")
.append(_entityInfo.id().columnName())
.append(" FROM ").append(_entityInfo.tableName())
.append(" where ");
for (int i = 0; i < where.length; i++) {
sql.append(where[i]).append('=').append('?');
if ((i + 1) < where.length)
sql.append(" AND ");
}
return sql.toString();
}
public String getSelectPkSql(String where)
{
StringBuilder sql = new StringBuilder("select ")
.append(_entityInfo.id().columnName())
.append(" FROM ").append(_entityInfo.tableName())
.append(' ').append(where);
return sql.toString();
}
public StringBuilder getWildSelect()
{
StringBuilder sql = new StringBuilder("select ");
FieldInfo[] fields = _entityInfo.getFields();
for (int i = 0; i < fields.length; i++) {
FieldInfo field = fields[i];
sql.append(field.columnName());
if ((i + 1) < fields.length)
sql.append(", ");
}
sql.append(" FROM ").append(_entityInfo.tableName());
return sql;
}
public String getSelectIds()
{
StringBuilder sql = new StringBuilder("select ")
.append(_entityInfo.id().columnName())
.append(" FROM ").append(_entityInfo.tableName());
return sql.toString();
}
public String getDeleteSql()
{
StringBuilder sql = new StringBuilder("delete from ")
.append(_entityInfo.tableName())
.append(" where ");
for (FieldInfo field : _entityInfo.getFields()) {
if (field.isId()) {
sql.append(field.columnName());
break;
}
}
sql.append(" = ?");
return sql.toString();
}
public String createDdl()
{
StringBuilder createDdl = new StringBuilder("create table ")
.append(_entityInfo.tableName()).append('(');
FieldInfo[] fields = _entityInfo.getFields();
for (int i = 0; i < fields.length; i++) {
FieldInfo field = _entityInfo.getFields()[i];
createDdl.append(field.columnName())
.append(' ')
.append(field.sqlType());
if (field.isId()) {
createDdl.append(" primary key");
}
if ((i + 1) < fields.length) {
createDdl.append(", ");
}
}
createDdl.append(')');
return createDdl.toString();
}
@Override
public MethodVault newMethod(Method method)
{
MethodParserVault parser
= new MethodParserVault(this, _entityInfo, method);
FindQueryVault,?,V> query = parser.parse();
if (query != null) {
return query;
}
else {
return super.newMethod(method);
}
/*
System.out.println("RQ: " + query);
switch (query.getMode()) {
case ALL: {
return createFindAllMethod(query);
}
case ONE: {
return createFindOneMethod(query);
}
default: {
return super.newMethod(method);
}
}
*/
}
/*
private ResourceMethod createFindOneMethod(ResourceQuery query)
{
return new FindOneMethod(this, _ampManager, query);
}
ResourceMethod createFindAllMethod(ResourceQuery query)
{
return new FindAllMethod(this, _ampManager, query);
}
*/
class NullResourceMethod implements MethodVault
{
@Override
public void invoke(Result result, Object[] args)
{
throw new IllegalStateException();
}
}
public String toString()
{
return this.getClass().getSimpleName()
+ "["
+ _db
+ ", "
+ _entityClass
+ "]";
}
public static String getColumnType(Class type)
{
String sqlType = _typeMap.get(type);
if (sqlType == null)
sqlType = "object";
return sqlType;
}
private interface IdReader
{
ID read(Cursor c);
}
private static class StringIdReader implements IdReader
{
@Override
public String read(Cursor c)
{
if (c == null)
return null;
return c.getString(1);
}
}
private static class IntIdReader implements IdReader
{
@Override
public Integer read(Cursor c)
{
if (c == null)
return null;
return c.getInt(1);
}
}
private static class LongIdReader implements IdReader
{
@Override
public Long read(Cursor c)
{
if (c == null)
return null;
return c.getLong(1);
}
}
private static class IdAssetReader implements IdReader
{
@Override
public IdAsset read(Cursor c)
{
if (c == null) {
return null;
}
return new IdAsset(c.getLong(1));
}
}
static {
_typeMap.put(byte.class, "integer");
_typeMap.put(Byte.class, "integer");
_typeMap.put(short.class, "integer");
_typeMap.put(Short.class, "integer");
_typeMap.put(char.class, "char");
_typeMap.put(Character.class, "char");
_typeMap.put(int.class, "integer");
_typeMap.put(Integer.class, "integer");
_typeMap.put(long.class, "long");
_typeMap.put(Long.class, "long");
_typeMap.put(float.class, "float");
_typeMap.put(Float.class, "float");
_typeMap.put(double.class, "double");
_typeMap.put(Double.class, "double");
_typeMap.put(String.class, "varchar");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy