|
From: <fab...@us...> - 2009-04-30 17:54:12
|
Revision: 4217
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4217&view=rev
Author: fabiomaulo
Date: 2009-04-30 17:54:10 +0000 (Thu, 30 Apr 2009)
Log Message:
-----------
continue work on executable HQL
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/AbstractStatementExecutor.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/BasicExecutor.cs
Added: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/AbstractStatementExecutor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/AbstractStatementExecutor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/AbstractStatementExecutor.cs 2009-04-30 17:54:10 UTC (rev 4217)
@@ -0,0 +1,23 @@
+using NHibernate.Engine;
+using NHibernate.SqlCommand;
+using log4net;
+
+namespace NHibernate.Hql.Ast.ANTLR.Exec
+{
+ public abstract class AbstractStatementExecutor : IStatementExecutor
+ {
+ private readonly ILog log;
+
+ protected AbstractStatementExecutor(HqlSqlWalker walker, ILog log)
+ {
+ Walker = walker;
+ this.log = log;
+ }
+
+ protected HqlSqlWalker Walker { get; private set; }
+
+ public abstract SqlString[] SqlStatements{get;}
+
+ public abstract int Execute(QueryParameters parameters, ISessionImplementor session);
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/BasicExecutor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/BasicExecutor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Exec/BasicExecutor.cs 2009-04-30 17:54:10 UTC (rev 4217)
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.Common;
+using Antlr.Runtime;
+using log4net;
+using NHibernate.Engine;
+using NHibernate.Exceptions;
+using NHibernate.Hql.Ast.ANTLR.Parameters;
+using NHibernate.Persister.Entity;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Hql.Ast.ANTLR.Exec
+{
+ public class BasicExecutor : AbstractStatementExecutor
+ {
+ private readonly IQueryable persister;
+ private static readonly ILog log = LogManager.GetLogger(typeof(QueryTranslatorImpl));
+ private SqlString sql;
+
+ public BasicExecutor(HqlSqlWalker walker, IQueryable persister) : base(walker, log)
+ {
+ this.persister = persister;
+ try
+ {
+
+ //SqlGenerator gen = new SqlGenerator(Factory);
+ //gen.statement(walker.getAST());
+ //sql = gen.GetSQL();
+ //gen.ParseErrorHandler.ThrowQueryException();
+ }
+ catch (RecognitionException e)
+ {
+ throw QuerySyntaxException.Convert(e);
+ }
+ }
+
+ protected ISessionFactoryImplementor Factory
+ {
+ get
+ {
+ return Walker.SessionFactoryHelper.Factory;
+ }
+ }
+
+ public override SqlString[] SqlStatements
+ {
+ get { return new[] {sql}; }
+ }
+
+ public override int Execute(QueryParameters parameters, ISessionImplementor session)
+ {
+ //CoordinateSharedCacheCleanup(session);
+
+ IDbCommand st = null;
+ RowSelection selection = parameters.RowSelection;
+
+ try
+ {
+ try
+ {
+ //st = session.Batcher.PrepareCommand(CommandType.Text, sql, parameterTypes);
+ IEnumerator<IParameterSpecification> paramSpecifications = Walker.Parameters.GetEnumerator();
+ int pos = 1;
+ while (paramSpecifications.MoveNext())
+ {
+ var paramSpec = paramSpecifications.Current;
+ pos += paramSpec.Bind(st, parameters, session, pos);
+ }
+ if (selection != null)
+ {
+ if (selection.Timeout != RowSelection.NoValue)
+ {
+ st.CommandTimeout = selection.Timeout;
+ }
+ }
+ return session.Batcher.ExecuteNonQuery(st);
+ }
+ finally
+ {
+ if (st != null)
+ {
+ session.Batcher.CloseCommand(st, null);
+ }
+ }
+ }
+ catch (DbException sqle)
+ {
+ throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
+ "could not execute update query", sql);
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs 2009-04-29 22:09:01 UTC (rev 4216)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs 2009-04-30 17:54:10 UTC (rev 4217)
@@ -6,10 +6,12 @@
using Iesi.Collections.Generic;
using log4net;
using NHibernate.Engine;
+using NHibernate.Hql.Ast.ANTLR.Exec;
using NHibernate.Hql.Ast.ANTLR.Loader;
using NHibernate.Hql.Ast.ANTLR.Parameters;
using NHibernate.Hql.Ast.ANTLR.Tree;
using NHibernate.Hql.Ast.ANTLR.Util;
+using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
@@ -27,8 +29,10 @@
private IDictionary<string, IFilter> _enabledFilters;
private readonly ISessionFactoryImplementor _factory;
private QueryLoader _queryLoader;
- private ParameterTranslationsImpl _paramTranslations;
-
+ private IStatementExecutor statementExecutor;
+ private IStatement sqlAst;
+ private ParameterTranslationsImpl _paramTranslations;
+ private IDictionary<string, string> tokenReplacements;
private HqlParseEngine _parser;
private HqlSqlTranslator _translator;
private HqlSqlGenerator _generator;
@@ -202,7 +206,7 @@
public IStatement SqlAST
{
- get { return _translator.SqlStatement; }
+ get { return sqlAst; }
}
public IList<IParameterSpecification> CollectedParameterSpecifications
@@ -322,27 +326,21 @@
return;
}
- if (replacements == null)
- {
- replacements = new Dictionary<string, string>();
- }
+ // Remember the parameters for the compilation.
+ tokenReplacements = replacements ?? new Dictionary<string, string>(1);
_shallowQuery = shallow;
try
{
// PHASE 1 : Parse the HQL into an AST.
- if (_parser == null)
- {
- _parser = new HqlParseEngine(_hql, true, _factory);
- _parser.Parse();
- }
+ HqlParseEngine parser = Parse(true);
// PHASE 2 : Analyze the HQL AST, and produce an SQL AST.
- _translator = new HqlSqlTranslator(_parser.Ast, _parser.Tokens, this, _factory, replacements,
- collectionRole);
- _translator.Translate();
-
+ HqlSqlWalker w = Analyze(parser, collectionRole);
+
+ sqlAst = (IStatement)w.statement().Tree;
+
// at some point the generate phase needs to be moved out of here,
// because a single object-level DML might spawn multiple SQL DML
// command executions.
@@ -356,16 +354,15 @@
if (_translator.SqlStatement.NeedsExecutor)
{
- throw new NotImplementedException(); // DML
-// statementExecutor = buildAppropriateStatementExecutor( w );
+ statementExecutor = BuildAppropriateStatementExecutor(w);
}
else
{
// PHASE 3 : Generate the SQL.
- _generator = new HqlSqlGenerator(_translator.SqlStatement, _parser.Tokens, _factory);
+ _generator = new HqlSqlGenerator(_translator.SqlStatement, parser.Tokens, _factory);
_generator.Generate();
-
- _queryLoader = new QueryLoader( this, _factory, _translator.SqlStatement.Walker.SelectClause );
+
+ _queryLoader = new QueryLoader(this, _factory, w.SelectClause);
}
_compiled = true;
@@ -389,6 +386,70 @@
_enabledFilters = null; //only needed during compilation phase...
}
+ private IStatementExecutor BuildAppropriateStatementExecutor(HqlSqlWalker walker)
+ {
+ if (walker.StatementType == HqlSqlWalker.DELETE)
+ {
+ FromElement fromElement = walker.GetFinalFromClause().GetFromElement();
+ IQueryable persister = fromElement.Queryable;
+ if (persister.IsMultiTable)
+ {
+ throw new NotSupportedException();
+ //return new MultiTableDeleteExecutor(walker);
+ }
+ else
+ {
+ return new BasicExecutor(walker, persister);
+ }
+ }
+ else if (walker.StatementType == HqlSqlWalker.UPDATE)
+ {
+ FromElement fromElement = walker.GetFinalFromClause().GetFromElement();
+ IQueryable persister = fromElement.Queryable;
+ if (persister.IsMultiTable)
+ {
+ // even here, if only properties mapped to the "base table" are referenced
+ // in the set and where clauses, this could be handled by the BasicDelegate.
+ // TODO : decide if it is better performance-wise to perform that check, or to simply use the MultiTableUpdateDelegate
+ throw new NotSupportedException();
+ //return new MultiTableUpdateExecutor(walker);
+ }
+ else
+ {
+ return new BasicExecutor(walker, persister);
+ }
+ }
+ else if (walker.StatementType == HqlSqlWalker.INSERT)
+ {
+ //var statement = (IStatement)walker.statement().Tree;
+
+ throw new QueryException("Unexpected statement type");
+ }
+ else
+ {
+ throw new QueryException("Unexpected statement type");
+ }
+ }
+
+ private HqlSqlWalker Analyze(HqlParseEngine parser, string collectionRole)
+ {
+ _translator = new HqlSqlTranslator(parser.Ast, parser.Tokens, this, _factory, tokenReplacements,
+ collectionRole);
+ _translator.Translate();
+
+ return _translator.SqlStatement.Walker;
+ }
+
+ private HqlParseEngine Parse(bool isFilter)
+ {
+ if (_parser == null)
+ {
+ _parser = new HqlParseEngine(_hql, isFilter, _factory);
+ _parser.Parse();
+ }
+ return _parser;
+ }
+
private void ErrorIfDML()
{
if (_translator.SqlStatement.NeedsExecutor)
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-04-29 22:09:01 UTC (rev 4216)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-04-30 17:54:10 UTC (rev 4217)
@@ -480,6 +480,8 @@
<Compile Include="Hql\Ast\ANTLR\CollectionProperties.cs" />
<Compile Include="Hql\Ast\ANTLR\DetailedSemanticException.cs" />
<Compile Include="Hql\Ast\ANTLR\ErrorCounter.cs" />
+ <Compile Include="Hql\Ast\ANTLR\Exec\AbstractStatementExecutor.cs" />
+ <Compile Include="Hql\Ast\ANTLR\Exec\BasicExecutor.cs" />
<Compile Include="Hql\Ast\ANTLR\Exec\IStatementExecutor.cs" />
<Compile Include="Hql\Ast\ANTLR\Generated\HqlLexer.cs" />
<Compile Include="Hql\Ast\ANTLR\Generated\HqlParser.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|