
sql.create_entity_manager.xslt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of orm Show documentation
Show all versions of orm Show documentation
Jinq legacy ORM for generating entity classes from XML
The newest version!
package ;
import ch.epfl.labos.iu.orm.DBSet;
import ch.epfl.labos.iu.orm.LazySet;
import ch.epfl.labos.iu.orm.VectorSet;
import org.jinq.tuples.Pair;
import org.jinq.tuples.Tuple3;
import org.jinq.tuples.Tuple4;
import org.jinq.tuples.Tuple5;
import ch.epfl.labos.iu.orm.QueryList;
import ch.epfl.labos.iu.orm.query.RowReader;
import ch.epfl.labos.iu.orm.query.SelectFromWhere;
import ch.epfl.labos.iu.orm.query2.JDBCConnectionInfo;
import ch.epfl.labos.iu.orm.query2.SQLQueryComposer;
import ch.epfl.labos.iu.orm.query2.SQLReader;
import ch.epfl.labos.iu.orm.query2.SQLReaderColumnDescription;
import ch.epfl.labos.iu.orm.query2.EntityManagerBackdoor;
import org.jinq.orm.annotations.EntitySupplier;
import org.jinq.orm.annotations.NoSideEffects;
import org.jinq.orm.stream.JinqStream;
import org.jinq.orm.stream.QueryJinqStream;
import java.io.Serializable;
import java.util.List;
import java.util.Vector;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.WeakHashMap;
import java.util.stream.Stream;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.lang.ref.WeakReference;
public class EntityManager implements EntityManagerBackdoor, Serializable
{
// Note: The EntityManager is not properly serializable, but some queries do access the
// entity manager. Those Java 8 lambdas need to be serialized to be decoded, so
// there needs to be a way to record some sort of placeholder entity manager when
// serializing the lambda.
transient DBManager db;
public int timeout = 0;
boolean cacheQueries = true;
boolean partialCacheQueries = true;
public EntityManager(DBManager db)
{
this.db = db;
this.timeout = db.timeout;
this.cacheQueries = db.useFullQueryCaching;
this.partialCacheQueries = db.usePartialQueryCaching;
}
void flushDirty()
{
// TODO: this
// TODO: Flushing of objects with references to other non-persisted objects that later become persisted
}
public abstract static class EntityReader<T> extends SQLReader <T>
{
EntityManager em;
String entityInternalClassName;
List<SQLReaderColumnDescription> columns = new Vector<SQLReaderColumnDescription>();
public EntityReader(EntityManager em, String entityInternalClassName)
{
this.em = em;
this.entityInternalClassName = entityInternalClassName;
}
public int getNumColumns()
{
// Currently assumes that each entry in the columns list takes
// up one column
//
return columns.size();
}
public int getColumnForField(String field)
{
for (int n = 0; n < columns.size(); n++)
{
if (field.equals(columns.get(n).field))
return n;
}
return -1;
}
public int getColumnIndexForColumnName(String col)
{
for (int n = 0; n < columns.size(); n++)
{
if (col.equals(columns.get(n).columnName))
return n;
}
return -1;
}
String [] getColumnNames()
{
String [] columnNames = new String[columns.size()];
for (int n = 0; n < columnNames.length; n++)
columnNames[n] = columns.get(n).columnName;
return columnNames;
}
SQLReader readerForType(String type)
{
if (type.equals("int"))
return new SQLReader.IntegerSQLReader();
else if (type.equals("float"))
return new SQLReader.FloatSQLReader();
else if (type.equals("double"))
return new SQLReader.DoubleSQLReader();
else if (type.equals("String"))
return new SQLReader.StringSQLReader();
else if (type.equals("Date"))
return new SQLReader.DateSQLReader();
return null;
}
public SQLReader getReaderForField(String field)
{
for (int n = 0; n < columns.size(); n++)
{
if (field.equals(columns.get(n).field))
{
String type = columns.get(n).type;
if (type != null)
return readerForType(type);
return null;
}
}
return null;
}
public boolean isCastConsistent(String internalName)
{
return entityInternalClassName.equals(internalName);
}
}
public SQLReader getReaderForEntity(String entity)
{
if (" ".equals(entity))
{
return new SQLReader(this);
}
return null;
}
public String[] getEntityColumnNames(String entity)
{
if (" ".equals(entity))
{
return new SQLReader(this).getColumnNames();
}
return null;
}
public String getTableForEntity(String entity)
{
if (" ".equals(entity))
{
return " ";
}
return null;
}
static class QueryCacheKey
{
QueryCacheKey(String context, Object baseQuery, Object lambda)
{
this.context = context;
this.baseQuery = baseQuery;
this.lambda = lambda;
}
public int hashCode()
{
return context.hashCode() ^ baseQuery.hashCode() ^ lambda.hashCode();
}
public boolean equals(Object o)
{
if (!(o instanceof QueryCacheKey)) return false;
QueryCacheKey other = (QueryCacheKey)o;
return other.context.equals(context)
&& other.baseQuery.equals(baseQuery)
&& other.lambda.equals(lambda);
}
String context;
Object baseQuery;
Object lambda;
}
static class QueryCacheValue
{
QueryCacheValue(QueryCacheKey key, Object cachedQuery)
{
this.key = key;
this.cachedQuery = cachedQuery;
}
QueryCacheKey key;
Object cachedQuery;
QueryCacheValue prev = null;
QueryCacheValue next = null;
}
transient Map<QueryCacheKey, QueryCacheValue> queryCache = new HashMap<QueryCacheKey, QueryCacheValue>();
final static int QUERY_CACHE_LIMIT = 500;
transient QueryCacheValue queryCacheLRU_head = null;
transient QueryCacheValue queryCacheLRU_tail = null;
int queryCacheSize = 0;
private void dequeueQueryCacheLRU(QueryCacheValue val)
{
queryCacheSize--;
if (val.next == null)
queryCacheLRU_tail = val.prev;
else
val.next.prev = val.prev;
if (val.prev == null)
queryCacheLRU_head = val.next;
else
val.prev.next = val.next;
val.prev = null;
val.next = null;
}
private void enqueueQueryCacheLRU(QueryCacheValue val)
{
// Add it to the end of the queue
if (queryCacheLRU_tail == null)
{
queryCacheLRU_tail = val;
queryCacheLRU_head = val;
}
else
{
val.prev = queryCacheLRU_tail;
queryCacheLRU_tail.next = val;
queryCacheLRU_tail = val;
}
// Check if we've overflowed
queryCacheSize++;
if (queryCacheSize > QUERY_CACHE_LIMIT)
{
QueryCacheValue toRemove = queryCacheLRU_head;
dequeueQueryCacheLRU(toRemove);
queryCache.remove(toRemove.key);
}
}
public Object getQueryCacheEntry(String context, Object baseQuery, Object lambda)
{
QueryCacheKey key = new QueryCacheKey(context, baseQuery, lambda);
QueryCacheValue cached = queryCache.get(key);
if (cached == null)
return null;
// Move it to the end of the queue
dequeueQueryCacheLRU(cached);
enqueueQueryCacheLRU(cached);
return cached.cachedQuery;
}
public void putQueryCacheEntry(String context, Object baseQuery, Object lambda, Object cachedQuery)
{
QueryCacheKey key = new QueryCacheKey(context, baseQuery, lambda);
QueryCacheValue cached = new QueryCacheValue(key, cachedQuery);
queryCache.put(key, cached);
enqueueQueryCacheLRU(cached);
}
static class GeneratedCachedQuery
{
GeneratedCachedQuery(Object key, Object cachedQuery)
{
this.key = key;
this.cachedQuery = cachedQuery;
}
Object key;
Object cachedQuery;
GeneratedCachedQuery prev = null;
GeneratedCachedQuery next = null;
}
transient Map<Object, GeneratedCachedQuery> generatedQueryCache = new HashMap<Object, GeneratedCachedQuery>();
final static int GENERATED_QUERY_CACHE_LIMIT = 500;
transient GeneratedCachedQuery generatedQueryCacheLRU_head = null;
transient GeneratedCachedQuery generatedQueryCacheLRU_tail = null;
int generatedQueryCacheSize = 0;
private void dequeueGeneratedQueryCacheLRU(GeneratedCachedQuery val)
{
generatedQueryCacheSize--;
if (val.next == null)
generatedQueryCacheLRU_tail = val.prev;
else
val.next.prev = val.prev;
if (val.prev == null)
generatedQueryCacheLRU_head = val.next;
else
val.prev.next = val.next;
val.prev = null;
val.next = null;
}
private void enqueueGeneratedQueryCacheLRU(GeneratedCachedQuery val)
{
// Add it to the end of the queue
if (generatedQueryCacheLRU_tail == null)
{
generatedQueryCacheLRU_tail = val;
generatedQueryCacheLRU_head = val;
}
else
{
val.prev = generatedQueryCacheLRU_tail;
generatedQueryCacheLRU_tail.next = val;
generatedQueryCacheLRU_tail = val;
}
// Check if we've overflowed
generatedQueryCacheSize++;
if (generatedQueryCacheSize > GENERATED_QUERY_CACHE_LIMIT)
{
GeneratedCachedQuery toRemove = generatedQueryCacheLRU_head;
dequeueGeneratedQueryCacheLRU(toRemove);
generatedQueryCache.remove(toRemove.key);
}
}
public Object getGeneratedQueryCacheEntry(Object queryRepresentation)
{
GeneratedCachedQuery cached = generatedQueryCache.get(queryRepresentation);
if (cached == null)
return null;
// Move it to the end of the queue
dequeueGeneratedQueryCacheLRU(cached);
enqueueGeneratedQueryCacheLRU(cached);
return cached.cachedQuery;
}
public void putGeneratedQueryCacheEntry(Object queryRepresentation, Object generatedQuery)
{
GeneratedCachedQuery cached = new GeneratedCachedQuery(queryRepresentation, generatedQuery);
generatedQueryCache.put(queryRepresentation, cached);
enqueueGeneratedQueryCacheLRU(cached);
}
public boolean isQueriesCached()
{
return cacheQueries || partialCacheQueries;
}
public boolean isPreparedStatementCached()
{
return cacheQueries;
}
}
// TODO: add plural forms of entity names
transient SQLQueryComposer< > Query;
transient DBSet< > ;
public DBSet< > all ()
{
return ;
}
@EntitySupplier(entityClass=" . ")
public JinqStream< > Stream()
{
return new QueryJinqStream<>( Query);
}
void dispose( obj)
{
flushDirty();
.remove(obj);
// delete from db immediately
String sql = "DELETE FROM "
+ " WHERE 1=1"
+ " AND = ? " ;
if (db.testOut != null) db.testOut.println(sql);
if (db.con != null)
{
try {
PreparedStatement stmt = db.con.prepareStatement(sql);
int idx = 0;
++idx;
stmt.setObject(idx, obj.get ());
stmt.executeUpdate();
stmt.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
void dirtyInstance( obj)
{
dirty .add(obj);
}
void newInstance( obj)
{
// TODO: Add handling of objects with auto-generated keys
// TODO: Add handling of objects whose keys are references to other objects
assert(obj.em == null);
obj.em = this;
// Fix references to other objects that happen to be keys
obj.set (
obj.get ().get ());
obj.set (
obj.get ().get ());
flushDirty();
// Add to DB immediately
.add(obj);
String sql = "INSERT INTO (";
boolean isFirst = true;
for (Map.Entry entry : map.entrySet())
{
if (!isFirst) sql = sql + ", ";
isFirst = false;
sql = sql + entry.getKey();
}
sql = sql + ") VALUES (";
for (int n = 0; n < map.size(); n++)
{
if (n != 0) sql = sql + ", ";
sql = sql + "?";
}
sql = sql + ")";
if (db.testOut != null) db.testOut.println(sql);
if (db.con != null)
{
try {
PreparedStatement stmt = db.con.prepareStatement(sql);
int idx = 1;
for (Map.Entry entry : map.entrySet())
{
stmt.setObject(idx, entry.getValue());
idx++;
}
stmt.executeUpdate();
stmt.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
known .put(obj.idKey(), new WeakReference< >(obj));
original .put(obj, ( )obj.copyForComparison());
}
create (ResultSet rs, int column) throws SQLException
{
obj = null;
key =
;
WeakReference< > ref = known .get(key);
if (ref != null) {
obj = ref.get();
if (obj != null)
{
// I'm not sure if this is necessary, but it's better to be safe
if (original .get(obj) == null)
original .put(obj, ( )obj.copyForComparison());
return obj;
}
}
obj = new (this, rs, column);
known .put(obj.idKey(), new WeakReference< >(obj));
original .put(obj, ( )obj.copyForComparison());
// TODO: this
return obj;
}
create (ResultSet rs, String prefix) throws SQLException
{
obj = null;
key =
;
WeakReference< > ref = known .get(key);
if (ref != null) {
obj = ref.get();
if (obj != null)
{
// I'm not sure if this is necessary, but it's better to be safe
if (original .get(obj) == null)
original .put(obj, ( )obj.copyForComparison());
return obj;
}
}
obj = new (this, rs, prefix);
known .put(obj.idKey(), new WeakReference< >(obj));
original .put(obj, ( )obj.copyForComparison());
// TODO: this
return obj;
}
transient HashSet< > dirty = new HashSet< >();
transient WeakHashMap< , > original = new WeakHashMap< , >();
transient WeakHashMap< , WeakReference< >> known = new WeakHashMap< , WeakReference< >>();
public static class SQLReader extends EntityReader< >
{
public SQLReader(EntityManager em)
{
super(em, " ");
columns.add(new SQLReaderColumnDescription(" ", " ", " "));
columns.add(new SQLReaderColumnDescription(null, " ", null));
columns.add(new SQLReaderColumnDescription(null, " ", null));
columns.add(new SQLReaderColumnDescription(null, " ", null));
columns.add(new SQLReaderColumnDescription(null, " ", null));
}
public readData(ResultSet result, int column)
{
try {
if (em.db.isQueryOnly)
return new (em, result, column);
else
return em.create (result, column);
} catch (SQLException e)
{
e.printStackTrace();
return null;
}
}
}
public class RowReader implements RowReader < >
{
public int column;
public String prefix;
public RowReader(String prefix)
{
this.prefix = prefix;
}
protected RowReader(String prefix, int column)
{
this.prefix = prefix;
this.column = column;
}
public readSqlRow(ResultSet rs)
{
try {
return create (rs, column);
} catch (SQLException e)
{
e.printStackTrace();
}
return null;
}
public void configureQuery(SelectFromWhere query)
{
int firstColumn = -1;
int col;
col = query.addSelection(prefix + ". ", prefix + "_ ");
if (firstColumn == -1) firstColumn = col;
col = query.addSelection(prefix + ". ", "LINK_" + prefix + "_ ");
if (firstColumn == -1) firstColumn = col;
col = query.addSelection(prefix + ". ", "LINK_" + prefix + "_ ");
if (firstColumn == -1) firstColumn = col;
col = query.addSelection(prefix + ". ", "LINK_" + prefix + "_ ");
if (firstColumn == -1) firstColumn = col;
col = query.addSelection(prefix + ". ", "LINK_" + prefix + "_ ");
if (firstColumn == -1) firstColumn = col;
column = firstColumn;
}
public RowReader < > copy()
{
return new RowReader(prefix, column);
}
public String queryString()
{
return prefix;
}
String Prefix;
public String materialize JoinString(SelectFromWhere query)
{
if ( Prefix == null)
{
String middlePrefix = query.addTable(" ");
Prefix = query.addTable(" ");
query.addWhereClause( Prefix + ". = " + prefix + ". ");
query.addWhereClause( Prefix + ". = " + middlePrefix + ". ");
query.addWhereClause(middlePrefix + ". = " + prefix + ". ");
}
return Prefix;
}
public RowReader materialize JoinRowReader(SelectFromWhere query)
{
return new RowReader(materialize JoinString(query));
}
String Prefix;
public String materialize JoinString(SelectFromWhere query)
{
if ( Prefix == null)
{
String middlePrefix = query.addTable(" ");
Prefix = query.addTable(" ");
query.addWhereClause(prefix + ". = " + Prefix + ". ");
query.addWhereClause(prefix + ". = " + middlePrefix + ". ");
query.addWhereClause(middlePrefix + ". = " + Prefix + ". ");
}
return Prefix;
}
public RowReader materialize JoinRowReader(SelectFromWhere query)
{
return new RowReader(materialize JoinString(query));
}
}
{
// SelectFromWhere query = new SelectFromWhere();
// String prefix = query.addTable(" ");
// RowReader < > reader = new RowReader(prefix);
// // TODO: Use of db con connection here that needs to be removed
// = new QueryLazySet< >(db.con, query, reader);
JDBCConnectionInfo jdbc = new JDBCConnectionInfo();
jdbc.connection = db.con;
jdbc.timeout = db.timeout;
jdbc.testOut = db.testOut;
SQLReader reader = new SQLReader(this);
SQLQueryComposer< > query =
new SQLQueryComposer< >(
this,
jdbc,
db.queryll,
reader,
reader.getColumnNames(),
" "
);
Query = query;
= new QueryList< >(query);
}
for ( obj : dirty )
{
String sql = "UPDATE SET ";
boolean isFirst = true;
for (Map.Entry entry : map.entrySet())
{
if (!isFirst) sql = sql + ", ";
isFirst = false;
sql = sql + entry.getKey() + "= ?";
}
sql = sql + " WHERE 1=1"
+ " AND = ? " ;
if (db.testOut != null) db.testOut.println(sql);
if (sql != null)
{
try {
PreparedStatement stmt = db.con.prepareStatement(sql);
int idx = 0;
for (Map.Entry entry : map.entrySet())
{
idx++;
stmt.setObject(idx, entry.getValue());
}
idx++;
stmt.setObject(idx, obj.get ());
stmt.executeUpdate();
stmt.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
DBSet< > added = obj.get ().comparisonClone();
added.removeAll(original .get(obj).get ());
DBSet< > removed = original .get(obj).get ().comparisonClone();
removed.removeAll(obj.get ());
for ( toobj: added)
{
HashMap<String, Object> linkmap = new HashMap<String, Object>();
linkmap.put(" ", obj.get ());
linkmap.put(" ", toobj.get ());
String linksql = "INSERT INTO (";
isFirst = true;
for (Map.Entry entry : linkmap.entrySet())
{
if (!isFirst) linksql = linksql + ", ";
isFirst = false;
linksql = linksql + entry.getKey();
}
linksql = linksql + ") VALUES (";
for (int n = 0; n < linkmap.size(); n++)
{
if (n != 0) linksql = linksql + ", ";
linksql = linksql + "?";
}
linksql = linksql + ")";
if (db.testOut != null) db.testOut.println(linksql);
if (db.con != null)
{
try {
PreparedStatement stmt = db.con.prepareStatement(linksql);
int idx = 0;
for (Map.Entry entry : linkmap.entrySet())
{
idx++;
stmt.setObject(idx, entry.getValue());
}
stmt.executeUpdate();
stmt.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
for ( toobj: removed)
{
HashMap<String, Object> linkmap = new HashMap<String, Object>();
linkmap.put(" ", obj.get ());
linkmap.put(" ", toobj.get ());
String linksql = "DELETE FROM "
+ " WHERE 1=1";
for (Map.Entry entry : linkmap.entrySet())
{
linksql = linksql + " AND " + entry.getKey() + " = ?";
}
if (db.testOut != null) db.testOut.println(linksql);
if (db.con != null)
{
try {
PreparedStatement stmt = db.con.prepareStatement(linksql);
int idx = 0;
for (Map.Entry entry : linkmap.entrySet())
{
idx++;
stmt.setObject(idx, entry.getValue());
}
stmt.executeUpdate();
stmt.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
dirty .clear();
NoKey
rs. (prefix + "_ ")
new <
,
>(
rs. (prefix + "_ ")
, rs. (prefix + "_ ")
)
NoKey
rs. (column + )
new <
,
>(
rs. (column + )
, rs. (column + )
)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy