From 27a28bf48e038aecd15616391b670441336226af Mon Sep 17 00:00:00 2001 From: singingbush Date: Sat, 11 Feb 2023 16:16:50 +0000 Subject: [PATCH] remove imports of std.stdio.writeln and instead use logger --- source/hibernated/metadata.d | 14 +++- source/hibernated/query.d | 131 ++++++++++++++++--------------- source/hibernated/session.d | 148 ++++++++++++++++++----------------- source/hibernated/type.d | 2 +- 4 files changed, 158 insertions(+), 137 deletions(-) diff --git a/source/hibernated/metadata.d b/source/hibernated/metadata.d index 56d01a6..956e093 100755 --- a/source/hibernated/metadata.d +++ b/source/hibernated/metadata.d @@ -18,7 +18,7 @@ import std.ascii; import std.conv; import std.datetime; import std.exception; -import std.stdio; +//import std.stdio : writeln; import std.string; import std.traits; import std.typecons; @@ -44,6 +44,13 @@ static if(__VERSION__ < 2080) { alias enforceHelper = enforce; } +// For backwards compatibily (since D 2.101, logger is no longer in std.experimental) +static if (__traits(compiles, (){ import std.logger; } )) { + import std.logger : trace, warning; +} else { + import std.experimental.logger : trace, warning; +} + abstract class EntityMetaData { @property size_t length(); @@ -3596,8 +3603,9 @@ class DBInfo { } tables = list; hasCircularRefs = hasCircularReferences(); - if (hasCircularRefs) - writeln("has circular references"); + if (hasCircularRefs) { + warning("has circular references"); + } } private bool hasCircularReferences() { for (int i=0; i 0, "@Embedded field property name should be specified when selecting " ~ aliasName ~ "." ~ item.prop.propertyName); item.prop = cast(PropertyInfo)ei.findProperty(propertyNames[0]); @@ -465,7 +472,7 @@ class QueryParser { // for each comma delimited item // in current version it can only be // {property} or {alias . property} optionally followed by ASC or DESC - //writeln("ORDER BY ITEM: " ~ to!string(start) ~ " .. " ~ to!string(end)); + //trace("ORDER BY ITEM: " ~ to!string(start) ~ " .. " ~ to!string(end)); bool asc = true; if (tokens[end - 1].type == TokenType.Keyword && tokens[end - 1].keyword == KeywordType.ASC) { end--; @@ -484,7 +491,7 @@ class QueryParser { enforceHelper!QuerySyntaxException(tokens[start + 2].type == TokenType.Ident, "Property name expected after entity alias in ORDER BY clause" ~ errorContext(tokens[start])); addOrderByClauseItem(cast(string)tokens[start].text, cast(string)tokens[start + 2].text, asc); } else { - //writeln("range: " ~ to!string(start) ~ " .. " ~ to!string(end)); + //trace("range: " ~ to!string(start) ~ " .. " ~ to!string(end)); enforceHelper!QuerySyntaxException(false, "Invalid ORDER BY clause (expected {property [ASC | DESC]} or {alias.property [ASC | DESC]} )" ~ errorContext(tokens[start])); } } @@ -493,19 +500,19 @@ class QueryParser { // for each comma delimited item // in current version it can only be // {property} or {alias . property} - //writeln("SELECT ITEM: " ~ to!string(start) ~ " .. " ~ to!string(end)); + //trace("SELECT ITEM: " ~ to!string(start) ~ " .. " ~ to!string(end)); enforceHelper!QuerySyntaxException(tokens[start].type == TokenType.Ident || tokens[start].type == TokenType.Alias, "Property name or alias expected in SELECT clause in query " ~ query ~ errorContext(tokens[start])); string aliasName; int p = start; if (tokens[p].type == TokenType.Alias) { - //writeln("select clause alias: " ~ tokens[p].text ~ " query: " ~ query); + //trace("select clause alias: " ~ tokens[p].text ~ " query: " ~ query); aliasName = cast(string)tokens[p].text; p++; enforceHelper!QuerySyntaxException(p == end || tokens[p].type == TokenType.Dot, "SELECT clause item is invalid (only [alias.]field{[.field2]}+ allowed) " ~ errorContext(tokens[start])); if (p < end - 1 && tokens[p].type == TokenType.Dot) p++; } else { - //writeln("select clause non-alias: " ~ tokens[p].text ~ " query: " ~ query); + //trace("select clause non-alias: " ~ tokens[p].text ~ " query: " ~ query); } string[] fieldNames; while (p < end && tokens[p].type == TokenType.Ident) { @@ -516,7 +523,7 @@ class QueryParser { // skipping dot p++; } - //writeln("parseSelectClauseItem pos=" ~ to!string(p) ~ " end=" ~ to!string(end)); + //trace("parseSelectClauseItem pos=" ~ to!string(p) ~ " end=" ~ to!string(end)); enforceHelper!QuerySyntaxException(p >= end, "SELECT clause item is invalid (only [alias.]field{[.field2]}+ allowed) " ~ errorContext(tokens[start])); addSelectClauseItem(aliasName, fieldNames); } @@ -547,19 +554,19 @@ class QueryParser { void parseWhereClause(int start, int end) { enforceHelper!QuerySyntaxException(start < end, "Invalid WHERE clause" ~ errorContext(tokens[start])); whereClause = new Token(tokens[start].pos, TokenType.Expression, tokens, start, end); - //writeln("before convert fields:\n" ~ whereClause.dump(0)); + //trace("before convert fields:\n" ~ whereClause.dump(0)); convertFields(whereClause.children); - //writeln("after convertFields before convertIsNullIsNotNull:\n" ~ whereClause.dump(0)); + //trace("after convertFields before convertIsNullIsNotNull:\n" ~ whereClause.dump(0)); convertIsNullIsNotNull(whereClause.children); - //writeln("after convertIsNullIsNotNull\n" ~ whereClause.dump(0)); + //trace("after convertIsNullIsNotNull\n" ~ whereClause.dump(0)); convertUnaryPlusMinus(whereClause.children); - //writeln("after convertUnaryPlusMinus\n" ~ whereClause.dump(0)); + //trace("after convertUnaryPlusMinus\n" ~ whereClause.dump(0)); foldBraces(whereClause.children); - //writeln("after foldBraces\n" ~ whereClause.dump(0)); + //trace("after foldBraces\n" ~ whereClause.dump(0)); foldOperators(whereClause.children); - //writeln("after foldOperators\n" ~ whereClause.dump(0)); + //trace("after foldOperators\n" ~ whereClause.dump(0)); dropBraces(whereClause.children); - //writeln("after dropBraces\n" ~ whereClause.dump(0)); + //trace("after dropBraces\n" ~ whereClause.dump(0)); } void foldBraces(ref Token[] items) { @@ -578,7 +585,7 @@ class QueryParser { } if (lastOpen == -1 && firstClose == -1) return; - //writeln("folding braces " ~ to!string(lastOpen) ~ " .. " ~ to!string(firstClose)); + //trace("folding braces " ~ to!string(lastOpen) ~ " .. " ~ to!string(firstClose)); enforceHelper!QuerySyntaxException(lastOpen >= 0 && lastOpen < firstClose, "Unpaired braces in WHERE clause" ~ errorContext(tokens[lastOpen])); Token folded = new Token(items[lastOpen].pos, TokenType.Braces, items, lastOpen + 1, firstClose); // size_t oldlen = items.length; @@ -689,7 +696,7 @@ class QueryParser { } } enforceHelper!QuerySyntaxException(idents.length == 0, "Unexpected extra field name " ~ idents[0] ~ errorContext(items[p])); - //writeln("full name = " ~ fullName); + //trace("full name = " ~ fullName); Token t = new Token(items[p].pos, TokenType.Field, fullName); t.entity = cast(EntityInfo)ei; t.field = cast(PropertyInfo)pi; @@ -763,7 +770,7 @@ class QueryParser { } if (bestOpPrecedency == -1) return; - //writeln("Found op " ~ items[bestOpPosition].toString() ~ " at position " ~ to!string(bestOpPosition) ~ " with priority " ~ to!string(bestOpPrecedency)); + //trace("Found op " ~ items[bestOpPosition].toString() ~ " at position " ~ to!string(bestOpPosition) ~ " with priority " ~ to!string(bestOpPrecedency)); if (t == OperatorType.NOT || t == OperatorType.UNARY_PLUS || t == OperatorType.UNARY_MINUS) { // fold unary enforceHelper!QuerySyntaxException(bestOpPosition < items.length && items[bestOpPosition + 1].isExpression(), "Syntax error in WHERE condition " ~ errorContext(items[bestOpPosition])); @@ -794,12 +801,12 @@ class QueryParser { foldCommaSeparatedList(items[bestOpPosition + 1]); replaceInPlace(items, bestOpPosition - 1, bestOpPosition + 2, [folded]); // fold value list - //writeln("IN operator found: " ~ folded.dump(3)); + //trace("IN operator found: " ~ folded.dump(3)); } else { // fold binary enforceHelper!QuerySyntaxException(bestOpPosition > 0, "Syntax error in WHERE condition - no left arg for binary operator " ~ errorContext(items[bestOpPosition])); enforceHelper!QuerySyntaxException(bestOpPosition < items.length - 1, "Syntax error in WHERE condition - no right arg for binary operator " ~ errorContext(items[bestOpPosition])); - //writeln("binary op " ~ items[bestOpPosition - 1].toString() ~ " " ~ items[bestOpPosition].toString() ~ " " ~ items[bestOpPosition + 1].toString()); + //trace("binary op " ~ items[bestOpPosition - 1].toString() ~ " " ~ items[bestOpPosition].toString() ~ " " ~ items[bestOpPosition + 1].toString()); enforceHelper!QuerySyntaxException(items[bestOpPosition - 1].isExpression(), "Syntax error in WHERE condition - wrong type of left arg for binary operator " ~ errorContext(items[bestOpPosition])); enforceHelper!QuerySyntaxException(items[bestOpPosition + 1].isExpression(), "Syntax error in WHERE condition - wrong type of right arg for binary operator " ~ errorContext(items[bestOpPosition])); Token folded = new Token(items[bestOpPosition - 1].pos, t, items[bestOpPosition].text, items[bestOpPosition - 1], items[bestOpPosition + 1]); @@ -859,7 +866,7 @@ class QueryParser { } if (selectClause[0].prop is null) { // object alias is specified: add all properties of object - //writeln("selected entity count: " ~ to!string(selectClause.length)); + //trace("selected entity count: " ~ to!string(selectClause.length)); res.setEntity(selectClause[0].from.entity); for(int i = 0; i < fromClause.length; i++) { FromClauseItem from = fromClause[i]; @@ -930,11 +937,11 @@ class QueryParser { res.appendSQL(join.joinType == JoinType.LeftJoin ? "LEFT JOIN " : "INNER JOIN "); res.appendSQL(dialect.quoteIfNeeded(join.entity.tableName) ~ " AS " ~ join.sqlAlias); res.appendSQL(" ON "); - //writeln("adding ON"); + //trace("adding ON"); if (join.baseProperty.oneToOne) { assert(join.baseProperty.columnName !is null || join.baseProperty.referencedProperty !is null); if (join.baseProperty.columnName !is null) { - //writeln("fk is in base"); + //trace("fk is in base"); res.appendSQL(base.sqlAlias); res.appendSQL("."); res.appendSQL(dialect.quoteIfNeeded(join.baseProperty.columnName)); @@ -943,7 +950,7 @@ class QueryParser { res.appendSQL("."); res.appendSQL(dialect.quoteIfNeeded(join.entity.getKeyProperty().columnName)); } else { - //writeln("fk is in join"); + //trace("fk is in join"); res.appendSQL(base.sqlAlias); res.appendSQL("."); res.appendSQL(dialect.quoteIfNeeded(base.entity.getKeyProperty().columnName)); @@ -954,7 +961,7 @@ class QueryParser { } } else if (join.baseProperty.manyToOne) { assert(join.baseProperty.columnName !is null, "ManyToOne should have JoinColumn as well"); - //writeln("fk is in base"); + //trace("fk is in base"); res.appendSQL(base.sqlAlias); res.appendSQL("."); res.appendSQL(dialect.quoteIfNeeded(join.baseProperty.columnName)); @@ -1682,14 +1689,14 @@ unittest { unittest { - //writeln("query unittest"); + //trace("query unittest"); import hibernated.tests; EntityMetaData schema = new SchemaInfoImpl!(User, Customer, AccountType, Address, Person, MoreInfo, EvenMoreInfo, Role); QueryParser parser = new QueryParser(schema, "SELECT a FROM User AS a WHERE id = :Id AND name != :skipName OR name IS NULL AND a.flags IS NOT NULL ORDER BY name, a.flags DESC"); assert(parser.parameterNames.length == 2); - //writeln("param1=" ~ parser.parameterNames[0]); - //writeln("param2=" ~ parser.parameterNames[1]); + //trace("param1=" ~ parser.parameterNames[0]); + //trace("param2=" ~ parser.parameterNames[1]); assert(parser.parameterNames[0] == "Id"); assert(parser.parameterNames[1] == "skipName"); assert(parser.fromClause.length == 1); @@ -1708,7 +1715,7 @@ unittest { parser = new QueryParser(schema, "SELECT a FROM User AS a WHERE ((id = :Id) OR (name LIKE 'a%' AND flags = (-5 + 7))) AND name != :skipName AND flags BETWEEN 2*2 AND 42/5 ORDER BY name, a.flags DESC"); assert(parser.whereClause !is null); - //writeln(parser.whereClause.dump(0)); + //trace(parser.whereClause.dump(0)); Dialect dialect = new MySQLDialect(); assert(dialect.quoteSqlString("abc") == "'abc'"); @@ -1717,11 +1724,11 @@ unittest { parser = new QueryParser(schema, "FROM User AS u WHERE id = :Id and u.name like '%test%'"); ParsedQuery q = parser.makeSQL(dialect); - //writeln(parser.whereClause.dump(0)); - //writeln(q.hql ~ "\n=>\n" ~ q.sql); + //trace(parser.whereClause.dump(0)); + //trace(q.hql ~ "\n=>\n" ~ q.sql); - //writeln(q.hql); - //writeln(q.sql); + //trace(q.hql); + //trace(q.sql); parser = new QueryParser(schema, "SELECT a FROM Person AS a LEFT JOIN a.moreInfo as b LEFT JOIN b.evenMore c WHERE a.id = :Id AND b.flags > 0 AND c.flags > 0"); assert(parser.fromClause.hasAlias("a")); assert(parser.fromClause.hasAlias("b")); @@ -1745,9 +1752,9 @@ unittest { assert(parser.fromClause.length == 3); assert(parser.fromClause[0].entity.tableName == "person"); assert(parser.fromClause[0].fetch == true); - //writeln("select fields [" ~ to!string(parser.fromClause[0].startColumn) ~ ", " ~ to!string(parser.fromClause[0].selectedColumns) ~ "]"); - //writeln("select fields [" ~ to!string(parser.fromClause[1].startColumn) ~ ", " ~ to!string(parser.fromClause[1].selectedColumns) ~ "]"); - //writeln("select fields [" ~ to!string(parser.fromClause[2].startColumn) ~ ", " ~ to!string(parser.fromClause[2].selectedColumns) ~ "]"); + //trace("select fields [" ~ to!string(parser.fromClause[0].startColumn) ~ ", " ~ to!string(parser.fromClause[0].selectedColumns) ~ "]"); + //trace("select fields [" ~ to!string(parser.fromClause[1].startColumn) ~ ", " ~ to!string(parser.fromClause[1].selectedColumns) ~ "]"); + //trace("select fields [" ~ to!string(parser.fromClause[2].startColumn) ~ ", " ~ to!string(parser.fromClause[2].selectedColumns) ~ "]"); assert(parser.fromClause[0].selectedColumns == 4); assert(parser.fromClause[1].entity.tableName == "person_info"); assert(parser.fromClause[1].joinType == JoinType.InnerJoin); @@ -1761,55 +1768,55 @@ unittest { assert(parser.fromClause[2].selectedColumns == 3); q = parser.makeSQL(dialect); - //writeln(q.hql); - //writeln(q.sql); + //trace(q.hql); + //trace(q.sql); parser = new QueryParser(schema, "FROM User WHERE id in (1, 2, (3 - 1 * 25) / 2, 4 + :Id, 5)"); - //writeln(parser.whereClause.dump(0)); + //trace(parser.whereClause.dump(0)); q = parser.makeSQL(dialect); - //writeln(q.hql); - //writeln(q.sql); + //trace(q.hql); + //trace(q.sql); parser = new QueryParser(schema, "FROM Customer WHERE users.id = 1"); q = parser.makeSQL(dialect); -// writeln(q.hql); -// writeln(q.sql); +// trace(q.hql); +// trace(q.sql); assert(q.sql == "SELECT _t1.id, _t1.name, _t1.zip, _t1.city, _t1.street_address, _t1.account_type_fk FROM customers AS _t1 LEFT JOIN users AS _t2 ON _t1.id=_t2.customer_fk WHERE _t2.id = 1"); parser = new QueryParser(schema, "FROM Customer WHERE id = 1"); q = parser.makeSQL(dialect); -// writeln(q.hql); -// writeln(q.sql); +// trace(q.hql); +// trace(q.sql); assert(q.sql == "SELECT _t1.id, _t1.name, _t1.zip, _t1.city, _t1.street_address, _t1.account_type_fk FROM customers AS _t1 WHERE _t1.id = 1"); parser = new QueryParser(schema, "FROM User WHERE roles.id = 1"); q = parser.makeSQL(dialect); - //writeln(q.hql); - //writeln(q.sql); + //trace(q.hql); + //trace(q.sql); assert(q.sql == "SELECT _t1.id, _t1.name, _t1.flags, _t1.comment, _t1.customer_fk FROM users AS _t1 LEFT JOIN role_users AS _t1_t2 ON _t1.id=_t1_t2.user_fk LEFT JOIN role AS _t2 ON _t1_t2.role_fk=_t2.id WHERE _t2.id = 1"); parser = new QueryParser(schema, "FROM Role WHERE users.id = 1"); q = parser.makeSQL(dialect); -// writeln(q.hql); -// writeln(q.sql); +// trace(q.hql); +// trace(q.sql); assert(q.sql == "SELECT _t1.id, _t1.name FROM role AS _t1 LEFT JOIN role_users AS _t1_t2 ON _t1.id=_t1_t2.role_fk LEFT JOIN users AS _t2 ON _t1_t2.user_fk=_t2.id WHERE _t2.id = 1"); parser = new QueryParser(schema, "FROM User WHERE customer.id = 1"); q = parser.makeSQL(dialect); -// writeln(q.hql); -// writeln(q.sql); +// trace(q.hql); +// trace(q.sql); assert(q.sql == "SELECT _t1.id, _t1.name, _t1.flags, _t1.comment, _t1.customer_fk FROM users AS _t1 LEFT JOIN customers AS _t2 ON _t1.customer_fk=_t2.id WHERE _t2.id = 1"); parser = new QueryParser(schema, "SELECT a2 FROM User AS a1 JOIN a1.roles AS a2 WHERE a1.id = 1"); q = parser.makeSQL(dialect); - //writeln(q.hql); - //writeln(q.sql); + //trace(q.hql); + //trace(q.sql); assert(q.sql == "SELECT _t2.id, _t2.name FROM users AS _t1 INNER JOIN role_users AS _t1_t2 ON _t1.id=_t1_t2.user_fk INNER JOIN role AS _t2 ON _t1_t2.role_fk=_t2.id WHERE _t1.id = 1"); parser = new QueryParser(schema, "SELECT a2 FROM Customer AS a1 JOIN a1.users AS a2 WHERE a1.id = 1"); q = parser.makeSQL(dialect); - //writeln(q.hql); - //writeln(q.sql); + //trace(q.hql); + //trace(q.sql); assert(q.sql == "SELECT _t2.id, _t2.name, _t2.flags, _t2.comment, _t2.customer_fk FROM customers AS _t1 INNER JOIN users AS _t2 ON _t1.id=_t2.customer_fk WHERE _t1.id = 1"); } diff --git a/source/hibernated/session.d b/source/hibernated/session.d index 2cc2faf..c2a7c20 100755 --- a/source/hibernated/session.d +++ b/source/hibernated/session.d @@ -16,7 +16,7 @@ module hibernated.session; import std.algorithm; import std.conv; -import std.stdio; +//import std.stdio : writeln; import std.exception; import std.variant; @@ -37,8 +37,14 @@ static if(__VERSION__ < 2080) { alias enforceHelper = enforce; } - -const TRACE_REFS = false; +// For backwards compatibily (since D 2.101, logger is no longer in std.experimental) +static if (__traits(compiles, (){ import std.logger; } )) { + pragma(msg, "Hibernated will log using 'std.logger'."); + import std.logger : trace; +} else { + pragma(msg, "Hibernated will log using 'std.experimental.logger'."); + import std.experimental.logger : trace; +} /// Factory to create HibernateD Sessions - similar to org.hibernate.SessionFactory interface SessionFactory { @@ -321,7 +327,7 @@ class SessionImpl : Session { } this(SessionFactoryImpl sessionFactory, EntityMetaData metaData, Dialect dialect, DataSource connectionPool) { - //writeln("Creating session"); + trace("Creating session"); this.sessionFactory = sessionFactory; this.metaData = metaData; this.dialect = dialect; @@ -357,7 +363,7 @@ class SessionImpl : Session { _accessor.onSessionClosed(); closed = true; sessionFactory.sessionClosed(this); - //writeln("closing connection"); + trace("closing connection"); assert(conn !is null); conn.close(); return null; @@ -422,17 +428,17 @@ class SessionImpl : Session { string query = metaData.generateFindByPkForEntity(dialect, info); enforceHelper!TransientObjectException(info.isKeySet(obj), "Cannot refresh entity " ~ info.name ~ ": no Id specified"); Variant id = info.getKey(obj); - //writeln("Finder query: " ~ query); + //trace("Finder query: " ~ query); PreparedStatement stmt = conn.prepareStatement(query); scope(exit) stmt.close(); stmt.setVariant(1, id); ResultSet rs = stmt.executeQuery(); - //writeln("returned rows: " ~ to!string(rs.getFetchSize())); + //trace("returned rows: " ~ to!string(rs.getFetchSize())); scope(exit) rs.close(); if (rs.next()) { - //writeln("reading columns"); + //trace("reading columns"); metaData.readAllColumns(obj, rs, 1); - //writeln("value: " ~ obj.toString); + //trace("value: " ~ obj.toString); } else { // not found! enforceHelper!ObjectNotFoundException(false, "Entity " ~ info.name ~ " with id " ~ to!string(id) ~ " not found"); @@ -462,7 +468,7 @@ class SessionImpl : Session { sql ~= list; Statement stmt = conn.createStatement(); scope(exit) stmt.close(); - //writeln("sql: " ~ sql); + //trace("sql: " ~ sql); stmt.executeUpdate(sql); } } @@ -596,7 +602,7 @@ class SessionImpl : Session { auto info = metaData.findEntityForObject(obj); enforceHelper!TransientObjectException(info.isKeySet(obj), "Cannot persist entity w/o key assigned"); string query = metaData.generateUpdateForEntity(dialect, info); - //writeln("Query: " ~ query); + //trace("Query: " ~ query); { PreparedStatement stmt = conn.prepareStatement(query); scope(exit) stmt.close(); @@ -655,7 +661,7 @@ class SessionFactoryImpl : SessionFactory { } this(EntityMetaData metaData, Dialect dialect, DataSource connectionPool) { - //writeln("Creating session factory"); + trace("Creating session factory"); this.metaData = metaData; this.dialect = dialect; this.connectionPool = connectionPool; @@ -675,7 +681,7 @@ class SessionFactoryImpl : SessionFactory { } override void close() { - //writeln("Closing session factory"); + trace("Closing session factory"); checkClosed(); closed = true; // if (observer !is null) @@ -779,19 +785,19 @@ class EntityCollections { @property Variant[] keys() { return _map.keys; } @property int length() { return cast(int)_map.length; } ref Object[] opIndex(Variant key) { - //writeln("searching for key " ~ key.toString); + //trace("searching for key " ~ key.toString); Variant id = normalize(key); if ((id in _map) is null) { - //writeln("creating new item"); + //trace("creating new item"); _map[id] = ObjectList(); } //assert(length > 0); - //writeln("returning item"); + //trace("returning item"); return _map[id].list; } void add(ref Variant id, Object obj) { auto item = opIndex(id); - //writeln("item count = " ~ to!string(item.length)); + //trace("item count = " ~ to!string(item.length)); item ~= obj; } } @@ -800,7 +806,7 @@ class PropertyLoadMap { private PropertyLoadItem[const PropertyInfo] _map; PropertyLoadItem opIndex(const PropertyInfo prop) { if ((prop in _map) is null) { - //writeln("creating new PropertyLoadItem for " ~ prop.propertyName); + //trace("creating new PropertyLoadItem for " ~ prop.propertyName); _map[prop] = new PropertyLoadItem(prop); } assert(_map.length > 0); @@ -843,13 +849,13 @@ class QueryImpl : Query ParameterValues params; this(SessionImpl sess, string queryString) { this.sess = sess; - //writeln("QueryImpl(): HQL: " ~ queryString); + //trace("QueryImpl(): HQL: " ~ queryString); QueryParser parser = new QueryParser(sess.metaData, queryString); - //writeln("parsing"); + //trace("parsing"); this.query = parser.makeSQL(sess.dialect); - //writeln("SQL: " ~ this.query.sql); + //trace("SQL: " ~ this.query.sql); params = query.createParams(); - //writeln("exiting QueryImpl()"); + //trace("exiting QueryImpl()"); } ///Get the query string. @@ -893,31 +899,31 @@ class QueryImpl : Query private Object readRelations(Object objectContainer, DataSetReader r, PropertyLoadMap loadMap) { Object[] relations = new Object[query.select.length]; - //writeln("select clause len = " ~ to!string(query.select.length)); + //trace("select clause len = " ~ to!string(query.select.length)); // read all related objects from DB row for (int i = 0; i < query.select.length; i++) { FromClauseItem from = query.select[i].from; - //writeln("reading " ~ from.entityName); + //trace("reading " ~ from.entityName); Object row; if (!from.entity.isKeyNull(r, from.startColumn)) { - //writeln("key is not null"); + //trace("key is not null"); Variant key = from.entity.getKey(r, from.startColumn); - //writeln("key is " ~ key.toString); + //trace("key is " ~ key.toString); row = sess.peekFromCache(from.entity.name, key); if (row is null) { - //writeln("row not found in cache"); + //trace("row not found in cache"); row = (objectContainer !is null && i == 0) ? objectContainer : from.entity.createEntity(); - //writeln("reading all columns"); + //trace("reading all columns"); sess.metaData.readAllColumns(row, r, from.startColumn); sess.putToCache(from.entity.name, key, row); } else if (objectContainer !is null) { - //writeln("copying all properties to existing container"); + //trace("copying all properties to existing container"); from.entity.copyAllProperties(objectContainer, row); } } relations[i] = row; } - //writeln("fill relations..."); + //trace("fill relations..."); // fill relations for (int i = 0; i < query.select.length; i++) { if (relations[i] is null) @@ -927,34 +933,34 @@ class QueryImpl : Query for (int j=0; j= 0) { Object rel = relations[rfrom.selectIndex]; pi.setObjectFunc(relations[i], rel); } else { if (pi.columnName !is null) { - static if (TRACE_REFS) writeln("relation " ~ pi.propertyName ~ " has column name"); + trace("relation " ~ pi.propertyName ~ " has column name"); if (r.isNull(from.startColumn + pi.columnOffset)) { // FK is null, set NULL to field pi.setObjectFunc(relations[i], null); - static if (TRACE_REFS) writeln("relation " ~ pi.propertyName ~ " has null FK"); + trace("relation " ~ pi.propertyName ~ " has null FK"); } else { Variant id = r.getVariant(from.startColumn + pi.columnOffset); Object existing = sess.peekFromCache(pi.referencedEntity.name, id); if (existing !is null) { - static if (TRACE_REFS) writeln("existing relation found in cache"); + trace("existing relation found in cache"); pi.setObjectFunc(relations[i], existing); } else { // FK is not null if (pi.lazyLoad) { // lazy load - static if (TRACE_REFS) writeln("scheduling lazy load for " ~ from.pathString ~ "." ~ pi.propertyName ~ " with FK " ~ id.toString); + trace("scheduling lazy load for " ~ from.pathString ~ "." ~ pi.propertyName ~ " with FK " ~ id.toString); LazyObjectLoader loader = new LazyObjectLoader(sess.accessor, pi, id); pi.setObjectDelegateFunc(relations[i], &loader.load); } else { // delayed load - static if (TRACE_REFS) writeln("relation " ~ pi.propertyName ~ " with FK " ~ id.toString() ~ " will be loaded later"); + trace("relation " ~ pi.propertyName ~ " with FK " ~ id.toString() ~ " will be loaded later"); loadMap.add(pi, id, relations[i]); // to load later } } @@ -968,12 +974,12 @@ class QueryImpl : Query Variant id = ei.getKey(relations[i]); if (pi.lazyLoad) { // lazy load - static if (TRACE_REFS) writeln("creating lazy loader for " ~ from.pathString ~ "." ~ pi.propertyName ~ " by FK " ~ id.toString); + trace("creating lazy loader for " ~ from.pathString ~ "." ~ pi.propertyName ~ " by FK " ~ id.toString); LazyCollectionLoader loader = new LazyCollectionLoader(sess.accessor, pi, id); pi.setCollectionDelegateFunc(relations[i], &loader.load); } else { // delayed load - static if (TRACE_REFS) writeln("Relation " ~ from.pathString ~ "." ~ pi.propertyName ~ " will be loaded later by FK " ~ id.toString); + trace("Relation " ~ from.pathString ~ "." ~ pi.propertyName ~ " will be loaded later by FK " ~ id.toString); loadMap.add(pi, id, relations[i]); // to load later } } @@ -991,15 +997,15 @@ class QueryImpl : Query loadMap = new PropertyLoadMap(loadMap); auto types = loadMap.keys; - static if (TRACE_REFS) writeln("delayedLoadRelations " ~ to!string(loadMap.length)); + trace("delayedLoadRelations " ~ to!string(loadMap.length)); foreach(pi; types) { - static if (TRACE_REFS) writeln("delayedLoadRelations " ~ pi.entity.name ~ "." ~ pi.propertyName); + trace("delayedLoadRelations " ~ pi.entity.name ~ "." ~ pi.propertyName); assert(pi.referencedEntity !is null); auto map = loadMap.remove(pi); if (map.length == 0) continue; - //writeln("delayedLoadRelations " ~ pi.entity.name ~ "." ~ pi.propertyName); + //trace("delayedLoadRelations " ~ pi.entity.name ~ "." ~ pi.propertyName); string keys = map.createCommaSeparatedKeyList(); if (pi.oneToOne || pi.manyToOne) { if (pi.columnName !is null) { @@ -1007,22 +1013,22 @@ class QueryImpl : Query Object[] list = sess.lookupCache(pi.referencedEntity.name, map.keys, unknownKeys); if (unknownKeys.length > 0) { string hql = "FROM " ~ pi.referencedEntity.name ~ " WHERE " ~ pi.referencedEntity.keyProperty.propertyName ~ " IN (" ~ createCommaSeparatedKeyList(unknownKeys) ~ ")"; - static if (TRACE_REFS) writeln("delayedLoadRelations: loading " ~ pi.propertyName ~ " HQL: " ~ hql); + trace("delayedLoadRelations: loading " ~ pi.propertyName ~ " HQL: " ~ hql); QueryImpl q = cast(QueryImpl)sess.createQuery(hql); Object[] fromDB = q.listObjects(null, loadMap); list ~= fromDB; - static if (TRACE_REFS) writeln("delayedLoadRelations: objects loaded " ~ to!string(fromDB.length)); + trace("delayedLoadRelations: objects loaded " ~ to!string(fromDB.length)); } else { - static if (TRACE_REFS) writeln("all objects found in cache"); + trace("all objects found in cache"); } - static if (TRACE_REFS) writeln("delayedLoadRelations: updating"); + trace("delayedLoadRelations: updating"); foreach(rel; list) { - static if (TRACE_REFS) writeln("delayedLoadRelations: reading key from " ~ pi.referencedEntity.name); + trace("delayedLoadRelations: reading key from " ~ pi.referencedEntity.name); Variant key = pi.referencedEntity.getKey(rel); - //writeln("map length before: " ~ to!string(map.length)); + //trace("map length before: " ~ to!string(map.length)); auto objectsToUpdate = map[key].list; - //writeln("map length after: " ~ to!string(map.length)); - //writeln("updating relations with key " ~ key.toString() ~ " (" ~ to!string(objectsToUpdate.length) ~ ")"); + //trace("map length after: " ~ to!string(map.length)); + //trace("updating relations with key " ~ key.toString() ~ " (" ~ to!string(objectsToUpdate.length) ~ ")"); foreach(obj; objectsToUpdate) { pi.setObjectFunc(obj, rel); } @@ -1032,29 +1038,29 @@ class QueryImpl : Query } } else if (pi.oneToMany || pi.manyToMany) { string hql = "FROM " ~ pi.referencedEntity.name ~ " WHERE " ~ pi.referencedPropertyName ~ "." ~ pi.referencedEntity.keyProperty.propertyName ~ " IN (" ~ keys ~ ")"; - static if (TRACE_REFS) writeln("delayedLoadRelations: loading " ~ pi.propertyName ~ " HQL: " ~ hql); + trace("delayedLoadRelations: loading " ~ pi.propertyName ~ " HQL: " ~ hql); QueryImpl q = cast(QueryImpl)sess.createQuery(hql); assert(q !is null); Object[] list = q.listObjects(null, loadMap); - static if (TRACE_REFS) writeln("delayedLoadRelations oneToMany/manyToMany: objects loaded " ~ to!string(list.length)); + trace("delayedLoadRelations oneToMany/manyToMany: objects loaded " ~ to!string(list.length)); EntityCollections collections = new EntityCollections(); // group by referenced PK foreach(rel; list) { - static if (TRACE_REFS) writeln("delayedLoadRelations oneToMany/manyToMany: reading reference from " ~ pi.referencedEntity.name ~ "." ~ pi.referencedProperty.propertyName ~ " joinColumn=" ~ pi.referencedProperty.columnName); + trace("delayedLoadRelations oneToMany/manyToMany: reading reference from " ~ pi.referencedEntity.name ~ "." ~ pi.referencedProperty.propertyName ~ " joinColumn=" ~ pi.referencedProperty.columnName); assert(pi.referencedProperty.manyToOne, "property referenced from OneToMany should be ManyToOne"); assert(pi.referencedProperty.getObjectFunc !is null); assert(rel !is null); - //writeln("delayedLoadRelations oneToMany: reading object " ~ rel.classinfo.toString); + //trace("delayedLoadRelations oneToMany: reading object " ~ rel.classinfo.toString); Object obj = pi.referencedProperty.getObjectFunc(rel); - //writeln("delayedLoadRelations oneToMany: object is read"); + //trace("delayedLoadRelations oneToMany: object is read"); if (obj !is null) { - //writeln("delayedLoadRelations oneToMany: object is not null"); - //writeln("pi.entity.name=" ~ pi.entity.name ~ ", obj is " ~ obj.classinfo.toString); - //writeln("obj = " ~ obj.toString); - //writeln("pi.entity.keyProperty=" ~ pi.entity.keyProperty.propertyName); + //trace("delayedLoadRelations oneToMany: object is not null"); + //trace("pi.entity.name=" ~ pi.entity.name ~ ", obj is " ~ obj.classinfo.toString); + //trace("obj = " ~ obj.toString); + //trace("pi.entity.keyProperty=" ~ pi.entity.keyProperty.propertyName); //assert(pi.entity.keyProperty.getFunc !is null); //Variant k = pi.entity.keyProperty.getFunc(obj); - //writeln("key=" ~ k.toString); + //trace("key=" ~ k.toString); Variant key = pi.entity.getKey(obj); collections[key] ~= rel; //collections.add(k, rel); @@ -1079,7 +1085,7 @@ class QueryImpl : Query /// Return the query results as a List of entity objects Object[] listObjects(Object placeFirstObjectHere, PropertyLoadMap loadMap) { - static if (TRACE_REFS) writeln("Entering listObjects " ~ query.hql); + trace("Entering listObjects " ~ query.hql); auto ei = query.entity; enforceHelper!SessionException(ei !is null, "No entity expected in result of query " ~ getQueryString()); params.checkAllParametersSet(); @@ -1088,7 +1094,7 @@ class QueryImpl : Query Object[] res; - //writeln("SQL: " ~ query.sql); + //trace("SQL: " ~ query.sql); PreparedStatement stmt = sess.conn.prepareStatement(query.sql); scope(exit) stmt.close(); params.applyParams(stmt); @@ -1098,17 +1104,17 @@ class QueryImpl : Query { scope(exit) rs.close(); while(rs.next()) { - //writeln("read relations..."); + //trace("read relations..."); Object row = readRelations(res.length > 0 ? null : placeFirstObjectHere, rs, loadMap); if (row !is null) res ~= row; } } if (loadMap.length > 0) { - static if (TRACE_REFS) writeln("relation properties scheduled for load: loadMap.length == " ~ to!string(loadMap.length)); + trace("relation properties scheduled for load: loadMap.length == " ~ to!string(loadMap.length)); delayedLoadRelations(loadMap); } - static if (TRACE_REFS) writeln("Exiting listObjects " ~ query.hql); + trace("Exiting listObjects " ~ query.hql); return res.length > 0 ? res : null; } @@ -1119,7 +1125,7 @@ class QueryImpl : Query Variant[][] res; - //writeln("SQL: " ~ query.sql); + //trace("SQL: " ~ query.sql); PreparedStatement stmt = sess.conn.prepareStatement(query.sql); scope(exit) stmt.close(); params.applyParams(stmt); @@ -1146,14 +1152,14 @@ class LazyObjectLoader { Variant id; SessionAccessor sess; this(SessionAccessor sess, const PropertyInfo pi, Variant id) { - static if (TRACE_REFS) writeln("Created lazy loader for " ~ pi.referencedEntityName ~ " with id " ~ id.toString); + trace("Created lazy loader for " ~ pi.referencedEntityName ~ " with id " ~ id.toString); this.pi = pi; this.id = id; this.sess = sess; } Object load() { - static if (TRACE_REFS) writeln("LazyObjectLoader.load()"); - static if (TRACE_REFS) writeln("lazy loading of " ~ pi.referencedEntityName ~ " with id " ~ id.toString); + trace("LazyObjectLoader.load()"); + trace("lazy loading of " ~ pi.referencedEntityName ~ " with id " ~ id.toString); return sess.get().loadObject(pi.referencedEntityName, id); } } @@ -1164,14 +1170,14 @@ class LazyCollectionLoader { SessionAccessor sess; this(SessionAccessor sess, const PropertyInfo pi, Variant fk) { assert(!pi.oneToMany || (pi.referencedEntity !is null && pi.referencedProperty !is null), "LazyCollectionLoader: No referenced property specified for OneToMany foreign key column"); - static if (TRACE_REFS) writeln("Created lazy loader for collection for references " ~ pi.entity.name ~ "." ~ pi.propertyName ~ " by id " ~ fk.toString); + trace("Created lazy loader for collection for references " ~ pi.entity.name ~ "." ~ pi.propertyName ~ " by id " ~ fk.toString); this.pi = pi; this.fk = fk; this.sess = sess; } Object[] load() { - static if (TRACE_REFS) writeln("LazyObjectLoader.load()"); - static if (TRACE_REFS) writeln("lazy loading of references " ~ pi.entity.name ~ "." ~ pi.propertyName ~ " by id " ~ fk.toString); + trace("LazyObjectLoader.load()"); + trace("lazy loading of references " ~ pi.entity.name ~ "." ~ pi.propertyName ~ " by id " ~ fk.toString); Object[] res = sess.get().loadReferencedObjects(pi.entity, pi.propertyName, fk); return res; } diff --git a/source/hibernated/type.d b/source/hibernated/type.d index a672e86..a41699a 100644 --- a/source/hibernated/type.d +++ b/source/hibernated/type.d @@ -15,7 +15,7 @@ module hibernated.type; import std.datetime; -import std.stdio; +//import std.stdio : writeln; import std.traits; import std.typecons;