예제 #1
0
        // DONE : H3.2 Executable query (now can be supported for named SQL query/ storedProcedure)
        public int PerformExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session)
        {
            CoordinateSharedCacheCleanup(session);

            if (queryParameters.Callable)
            {
                throw new ArgumentException("callable not yet supported for native queries");
            }

            RowSelection selection = queryParameters.RowSelection;

            int result;

            try
            {
                var       parametersSpecifications = customQuery.CollectedParametersSpecifications.ToList();
                SqlString sql = ExpandDynamicFilterParameters(customQuery.SQL, parametersSpecifications, session);
                // After the last modification to the SqlString we can collect all parameters types.
                parametersSpecifications.ResetEffectiveExpectedType(queryParameters);

                var       sqlParametersList = sql.GetParameters().ToList();
                SqlType[] sqlTypes          = parametersSpecifications.GetQueryParameterTypes(sqlParametersList, session.Factory);

                var ps = session.Batcher.PrepareCommand(CommandType.Text, sql, sqlTypes);

                try
                {
                    if (selection != null && selection.Timeout != RowSelection.NoValue)
                    {
                        // NH Difference : set Timeout for native query
                        ps.CommandTimeout = selection.Timeout;
                    }

                    foreach (IParameterSpecification parameterSpecification in parametersSpecifications)
                    {
                        parameterSpecification.Bind(ps, sqlParametersList, queryParameters, session);
                    }

                    result = session.Batcher.ExecuteNonQuery(ps);
                }
                finally
                {
                    if (ps != null)
                    {
                        session.Batcher.CloseCommand(ps, null);
                    }
                }
            }
            catch (HibernateException)
            {
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
                                                 "could not execute native bulk manipulation query:" + sourceQuery);
            }

            return(result);
        }
예제 #2
0
        // Need this method call in this class rather than the base class to ensure Prepare is called... if only it was virtual :(
        protected void ExecuteBatch(IDbCommand ps)
        {
            #region NHibernate code
            Log.Debug("Executing batch");
            CheckReaders();
            Prepare(_currentBatch.BatchCommand);
            if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
            {
                Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
                _currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
            }

            int rowsAffected;
            try
            {
                rowsAffected = _currentBatch.ExecuteNonQuery();
            }
            catch (DbException e)
            {
                throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
            }

            Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowsAffected);

            _currentBatch.Dispose();
            _totalExpectedRowsAffected = 0;
            _currentBatch = CreateConfiguredBatch();
            #endregion
        }
        protected override void DoExecuteBatch(DbCommand ps)
        {
            try
            {
                Log.Debug("Executing batch");
                CheckReaders();
                Prepare(_currentBatch.BatchCommand);
                if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
                {
                    Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
                }
                int rowsAffected;
                try
                {
                    rowsAffected = _currentBatch.ExecuteNonQuery();
                }
                catch (DbException e)
                {
                    throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
                }

                Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowsAffected, ps);
            }
            finally
            {
                ClearCurrentBatch();
            }
        }
예제 #4
0
        protected override void DoExecuteBatch(IDbCommand ps)
        {
            Log.DebugFormat("Executing batch");
            CheckReaders();
            if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
            {
                Factory.Settings.SqlStatementLogger.LogBatchCommand(currentBatchCommandsLog.ToString());
                currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
            }

            int rowsAffected;

            try {
                rowsAffected = currentBatch.ExecuteNonQuery();
            }
            catch (DbException e) {
                throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
            }

            Expectations.VerifyOutcomeBatched(totalExpectedRowsAffected, rowsAffected);

            currentBatch.Dispose();
            totalExpectedRowsAffected = 0;
            currentBatch = CreateConfiguredBatch();
        }
예제 #5
0
        private void PostNext()
        {
            log.Debug("attempting to retrieve next results");
            bool readResult;

            try
            {
                readResult = _reader.Read();
                if (!readResult)
                {
                    log.Debug("exhausted results");
                    _currentResult = null;
                    _session.Batcher.CloseCommand(_cmd, _reader);
                }
                else
                {
                    log.Debug("retrieved next results");
                }
            }
            catch (DbException e)
            {
                throw ADOExceptionHelper.Convert(_session.Factory.SQLExceptionConverter, e, "Error executing Enumerable() query",
                                                 new SqlString(_cmd.CommandText));
            }
        }
예제 #6
0
        public ITableMetadata GetTableMetadata(string name, string schema, string catalog, bool isQuoted)
        {
            string         identifier = Identifier(catalog, schema, name);
            ITableMetadata table;

            tables.TryGetValue(identifier, out table);
            if (table != null)
            {
                return(table);                // EARLY exit
            }
            try
            {
                DataTable metaInfo;
                if ((isQuoted && meta.StoresMixedCaseQuotedIdentifiers))
                {
                    metaInfo = meta.GetTables(catalog, schema, name, Types);
                }
                else
                {
                    if ((isQuoted && meta.StoresUpperCaseQuotedIdentifiers) || (!isQuoted && meta.StoresUpperCaseIdentifiers))
                    {
                        metaInfo =
                            meta.GetTables(StringHelper.ToUpperCase(catalog), StringHelper.ToUpperCase(schema),
                                           StringHelper.ToUpperCase(name), Types);
                    }
                    else
                    {
                        if ((isQuoted && meta.StoresLowerCaseQuotedIdentifiers) || (!isQuoted && meta.StoresLowerCaseIdentifiers))
                        {
                            metaInfo =
                                meta.GetTables(StringHelper.ToLowerCase(catalog), StringHelper.ToLowerCase(schema),
                                               StringHelper.ToLowerCase(name), Types);
                        }
                        else
                        {
                            metaInfo = meta.GetTables(catalog, schema, name, Types);
                        }
                    }
                }
                DataRowCollection rows = metaInfo.Rows;

                foreach (DataRow tableRow in rows)
                {
                    string tableName = Convert.ToString(tableRow[meta.ColumnNameForTableName]);
                    if (name.Equals(tableName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        table = meta.GetTableMetadata(tableRow, extras);
                        tables[identifier] = table;
                        return(table);
                    }
                }

                log.Info("table not found: {0}", name);
                return(null);
            }
            catch (DbException sqle)
            {
                throw ADOExceptionHelper.Convert(sqlExceptionConverter, sqle, "could not get table metadata: " + name);
            }
        }
예제 #7
0
 /// <summary>
 /// Generate an <see cref="Int16"/>, <see cref="Int32"/>, or <see cref="Int64"/>
 /// for the identifier by using a database sequence.
 /// </summary>
 /// <param name="session">The <see cref="ISessionImplementor"/> this id is being generated in.</param>
 /// <param name="obj">The entity for which the id is being generated.</param>
 /// <returns>The new identifier as a <see cref="Int16"/>, <see cref="Int32"/>, or <see cref="Int64"/>.</returns>
 public virtual object Generate(ISessionImplementor session, object obj)
 {
     try
     {
         var          cmd    = session.Batcher.PrepareCommand(CommandType.Text, sql, SqlTypeFactory.NoTypes);
         DbDataReader reader = null;
         try
         {
             reader = session.Batcher.ExecuteReader(cmd);
             try
             {
                 reader.Read();
                 object result = IdentifierGeneratorFactory.Get(reader, identifierType, session);
                 if (log.IsDebugEnabled)
                 {
                     log.Debug("Sequence identifier generated: " + result);
                 }
                 return(result);
             }
             finally
             {
                 reader.Close();
             }
         }
         finally
         {
             session.Batcher.CloseCommand(cmd, reader);
         }
     }
     catch (DbException sqle)
     {
         log.Error("error generating sequence", sqle);
         throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not get next sequence value");
     }
 }
예제 #8
0
        /// <summary>
        /// Load an instance by a unique key that is not the primary key.
        /// </summary>
        /// <param name="entityName">The name of the entity to load </param>
        /// <param name="uniqueKeyPropertyName">The name of the property defining the unique key. </param>
        /// <param name="key">The unique key property value. </param>
        /// <param name="session">The originating session. </param>
        /// <returns> The loaded entity </returns>
        public object LoadByUniqueKey(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session)
        {
            ISessionFactoryImplementor factory   = session.Factory;
            IUniqueKeyLoadable         persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

            //TODO: implement caching?! proxies?!

            EntityUniqueKey euk =
                new EntityUniqueKey(entityName, uniqueKeyPropertyName, key, GetIdentifierOrUniqueKeyType(factory),
                                    session.EntityMode, session.Factory);

            IPersistenceContext persistenceContext = session.PersistenceContext;

            try
            {
                object result = persistenceContext.GetEntity(euk);
                if (result == null)
                {
                    result = persister.LoadByUniqueKey(uniqueKeyPropertyName, key, session);
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }
 protected Exception Convert(Exception sqlException, string message)
 {
     using (new SessionIdLoggingContext(SessionId))
     {
         return(ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqlException, message));
     }
 }
        public async Task <object> GenerateAsync(ISessionImplementor session, object obj, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var sql = new SqlString(session.Factory.Dialect.SelectGUIDString);

            try
            {
                var          st     = await(session.Batcher.PrepareCommandAsync(CommandType.Text, sql, SqlTypeFactory.NoTypes, cancellationToken)).ConfigureAwait(false);
                DbDataReader reader = null;
                try
                {
                    reader = await(session.Batcher.ExecuteReaderAsync(st, cancellationToken)).ConfigureAwait(false);
                    object result;
                    try
                    {
                        await(reader.ReadAsync(cancellationToken)).ConfigureAwait(false);
                        result = await(IdentifierGeneratorFactory.GetAsync(reader, identifierType, session, cancellationToken)).ConfigureAwait(false);
                    }
                    finally
                    {
                        reader.Close();
                    }
                    log.Debug("GUID identifier generated: " + result);
                    return(result);
                }
                finally
                {
                    session.Batcher.CloseCommand(st, reader);
                }
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not retrieve GUID", sql);
            }
        }
        protected override async Task DoExecuteBatchAsync(DbCommand ps, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            try
            {
                Log.Debug("Executing batch");
                await(CheckReadersAsync(cancellationToken)).ConfigureAwait(false);
                await(PrepareAsync(_currentBatch.BatchCommand, cancellationToken)).ConfigureAwait(false);
                if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
                {
                    Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
                }
                int rowsAffected;
                try
                {
                    rowsAffected = _currentBatch.ExecuteNonQuery();
                }
                catch (DbException e)
                {
                    throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
                }

                Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowsAffected, ps);
            }
            finally
            {
                ClearCurrentBatch();
            }
        }
예제 #12
0
 public object Generate(ISessionImplementor session, object obj)
 {
     try
     {
         IDbCommand  cmd    = session.Batcher.PrepareCommand(CommandType.Text, _sql, SqlTypeFactory.NoTypes);
         IDataReader reader = null;
         try
         {
             reader = session.Batcher.ExecuteReader(cmd);
             try
             {
                 reader.Read();
                 object result = IdentifierGeneratorFactory.Get(reader, NHibernateUtil.String, session);
                 return(result);
             }
             finally
             {
                 reader.Close();
             }
         }
         finally
         {
             session.Batcher.CloseCommand(cmd, reader);
         }
     }
     catch (DbException sqle)
     {
         throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not get next sequence value");
     }
 }
예제 #13
0
        public object Generate(ISessionImplementor session, object obj)
        {
            var sql = new SqlString(session.Factory.Dialect.SelectGUIDString);

            try
            {
                IDbCommand  st     = session.Batcher.PrepareCommand(CommandType.Text, sql, SqlTypeFactory.NoTypes);
                IDataReader reader = null;
                try
                {
                    reader = session.Batcher.ExecuteReader(st);
                    object result;
                    try
                    {
                        reader.Read();
                        result = IdentifierGeneratorFactory.Get(reader, identifierType, session);
                    }
                    finally
                    {
                        reader.Close();
                    }
                    log.Debug("GUID identifier generated: " + result);
                    return(result);
                }
                finally
                {
                    session.Batcher.CloseCommand(st, reader);
                }
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not retrieve GUID", sql);
            }
        }
예제 #14
0
        public async Task LockAsync(object id, object version, object obj, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ISessionFactoryImplementor factory = session.Factory;

            try
            {
                var          st = await(session.Batcher.PrepareCommandAsync(CommandType.Text, sql, lockable.IdAndVersionSqlTypes, cancellationToken)).ConfigureAwait(false);
                DbDataReader rs = null;
                try
                {
                    await(lockable.IdentifierType.NullSafeSetAsync(st, id, 0, session, cancellationToken)).ConfigureAwait(false);
                    if (lockable.IsVersioned)
                    {
                        await(lockable.VersionType.NullSafeSetAsync(st, version, lockable.IdentifierType.GetColumnSpan(factory), session, cancellationToken)).ConfigureAwait(false);
                    }

                    rs = await(session.Batcher.ExecuteReaderAsync(st, cancellationToken)).ConfigureAwait(false);
                    try
                    {
                        if (!await(rs.ReadAsync(cancellationToken)).ConfigureAwait(false))
                        {
                            if (factory.Statistics.IsStatisticsEnabled)
                            {
                                factory.StatisticsImplementor.OptimisticFailure(lockable.EntityName);
                            }
                            throw new StaleObjectStateException(lockable.EntityName, id);
                        }
                    }
                    finally
                    {
                        rs.Close();
                    }
                }
                finally
                {
                    session.Batcher.CloseCommand(st, rs);
                }
            }
            catch (OperationCanceledException) { throw; }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                var exceptionContext = new AdoExceptionContextInfo
                {
                    SqlException = sqle,
                    Message      = "could not lock: " + MessageHelper.InfoString(lockable, id, factory),
                    Sql          = sql.ToString(),
                    EntityName   = lockable.EntityName,
                    EntityId     = id
                };
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, exceptionContext);
            }
        }
        public void Lock(object id, object version, object obj, ISessionImplementor session)
        {
            ISessionFactoryImplementor factory = session.Factory;

            try
            {
                IDbCommand  st = session.Batcher.PrepareCommand(CommandType.Text, sql, lockable.IdAndVersionSqlTypes);
                IDataReader rs = null;
                try
                {
                    lockable.IdentifierType.NullSafeSet(st, id, 0, session);
                    if (lockable.IsVersioned)
                    {
                        lockable.VersionType.NullSafeSet(st, version, lockable.IdentifierType.GetColumnSpan(factory), session);
                    }

                    rs = session.Batcher.ExecuteReader(st);
                    try
                    {
                        if (!rs.Read())
                        {
                            if (factory.Statistics.IsStatisticsEnabled)
                            {
                                factory.StatisticsImplementor.OptimisticFailure(lockable.EntityName);
                            }
                            throw new StaleObjectStateException(lockable.EntityName, id);
                        }
                    }
                    finally
                    {
                        rs.Close();
                    }
                }
                finally
                {
                    session.Batcher.CloseCommand(st, rs);
                }
            }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                var exceptionContext = new AdoExceptionContextInfo
                {
                    SqlException = sqle,
                    Message      = "could not lock: " + MessageHelper.InfoString(lockable, id, factory),
                    Sql          = sql.ToString(),
                    EntityName   = lockable.EntityName,
                    EntityId     = id
                };
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, exceptionContext);
            }
        }
예제 #16
0
        // DONE : H3.2 Executable query (now can be supported for named SQL query/ storedProcedure)
        public int PerformExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session)
        {
            CoordinateSharedCacheCleanup(session);

            if (queryParameters.Callable)
            {
                throw new ArgumentException("callable not yet supported for native queries");
            }

            RowSelection selection = queryParameters.RowSelection;

            int result;

            try
            {
                queryParameters.ProcessFilters(customQuery.SQL, session);
                SqlString sql      = queryParameters.FilteredSQL;
                SqlType[] sqlTypes = queryParameters.PrepareParameterTypes(sql, session.Factory, GetNamedParameterLocs, 0, false, false);

                IDbCommand ps = session.Batcher.PrepareCommand(CommandType.Text, sql, sqlTypes);

                try
                {
                    if (selection != null && selection.Timeout != RowSelection.NoValue)
                    {
                        // NH Difference : set Timeout for native query
                        ps.CommandTimeout = selection.Timeout;
                    }
                    // NH Different behavior:
                    // The inital value is 0 (initialized to 1 in JAVA)
                    // The responsibility of parameter binding was entirely moved to QueryParameters
                    // to deal with positionslParameter+NamedParameter+ParameterOfFilters

                    queryParameters.BindParameters(ps, 0, session);
                    result = session.Batcher.ExecuteNonQuery(ps);
                }
                finally
                {
                    if (ps != null)
                    {
                        session.Batcher.CloseCommand(ps, null);
                    }
                }
            }
            catch (HibernateException)
            {
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
                                                 "could not execute native bulk manipulation query:" + sourceQuery);
            }

            return(result);
        }
예제 #17
0
        public void Lock(object id, object version, object obj, ISessionImplementor session)
        {
            if (!lockable.IsVersioned)
            {
                throw new HibernateException("write locks via update not supported for non-versioned entities [" + lockable.EntityName + "]");
            }
            // todo : should we additionally check the current isolation mode explicitly?
            ISessionFactoryImplementor factory = session.Factory;

            try
            {
                IDbCommand st = session.Batcher.PrepareCommand(CommandType.Text, sql, lockable.IdAndVersionSqlTypes);
                try
                {
                    lockable.VersionType.NullSafeSet(st, version, 1, session);
                    int offset = 2;

                    lockable.IdentifierType.NullSafeSet(st, id, offset, session);
                    offset += lockable.IdentifierType.GetColumnSpan(factory);

                    if (lockable.IsVersioned)
                    {
                        lockable.VersionType.NullSafeSet(st, version, offset, session);
                    }

                    int affected = session.Batcher.ExecuteNonQuery(st);
                    if (affected < 0)
                    {
                        factory.StatisticsImplementor.OptimisticFailure(lockable.EntityName);
                        throw new StaleObjectStateException(lockable.EntityName, id);
                    }
                }
                finally
                {
                    session.Batcher.CloseCommand(st, null);
                }
            }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                var exceptionContext = new AdoExceptionContextInfo
                {
                    SqlException = sqle,
                    Message      = "could not lock: " + MessageHelper.InfoString(lockable, id, factory),
                    Sql          = sql.ToString(),
                    EntityName   = lockable.EntityName,
                    EntityId     = id
                };
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, exceptionContext);
            }
        }
예제 #18
0
 public void DoWork(DbConnection connection, DbTransaction transaction)
 {
     try
     {
         generatedValue = owner.DoWorkInCurrentTransaction(session, connection, transaction);
     }
     catch (DbException sqle)
     {
         throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not get or update next value", null);
     }
 }
        public object PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
        {
            try
            {
                // prepare and execute the insert
                IDbCommand insert = session.Batcher.PrepareCommand(insertSQL.CommandType, insertSQL.Text, insertSQL.ParameterTypes);
                try
                {
                    binder.BindValues(insert);
                    session.Batcher.ExecuteNonQuery(insert);
                }
                finally
                {
                    session.Batcher.CloseCommand(insert, null);
                }
            }
            catch (DbException sqle)
            {
                throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
                                                 "could not insert: " + persister.GetInfoString(), insertSQL.Text);
            }

            SqlString selectSQL = SelectSQL;

            using (new SessionIdLoggingContext(session.SessionId))
                try
                {
                    //fetch the generated id in a separate query
                    IDbCommand idSelect = session.Batcher.PrepareCommand(CommandType.Text, selectSQL, ParametersTypes);
                    try
                    {
                        BindParameters(session, idSelect, binder.Entity);
                        IDataReader rs = session.Batcher.ExecuteReader(idSelect);
                        try
                        {
                            return(GetResult(session, rs, binder.Entity));
                        }
                        finally
                        {
                            session.Batcher.CloseReader(rs);
                        }
                    }
                    finally
                    {
                        session.Batcher.CloseCommand(idSelect, null);
                    }
                }
                catch (DbException sqle)
                {
                    throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle,
                                                     "could not retrieve generated id after insert: " + persister.GetInfoString(),
                                                     insertSQL.Text);
                }
        }
예제 #20
0
 public async Task DoWorkAsync(DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     try
     {
         generatedValue = await(owner.DoWorkInCurrentTransactionAsync(session, connection, transaction, cancellationToken)).ConfigureAwait(false);
     }
     catch (DbException sqle)
     {
         throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, sqle, "could not get or update next value", null);
     }
 }
예제 #21
0
        public override int Execute(QueryParameters parameters, ISessionImplementor session)
        {
            CoordinateSharedCacheCleanup(session);

            IDbCommand   st        = null;
            RowSelection selection = parameters.RowSelection;

            try
            {
                try
                {
                    CheckParametersExpectedType(parameters);                     // NH Different behavior (NH-1898)
                    var parameterTypes = new List <SqlType>(Parameters.Count);
                    foreach (var parameterSpecification in Parameters)
                    {
                        if (parameterSpecification.ExpectedType == null)
                        {
                            throw new QuerySyntaxException("Can't determine SqlType of parameter " + parameterSpecification.RenderDisplayInfo() + "\n Possible cause: wrong case-sensitive property-name.");
                        }
                        parameterTypes.AddRange(parameterSpecification.ExpectedType.SqlTypes(Factory));
                    }
                    st = session.Batcher.PrepareCommand(CommandType.Text, sql, parameterTypes.ToArray());
                    IEnumerator <IParameterSpecification> paramSpecifications = Parameters.GetEnumerator();
                    // NH Different behavior: The inital value is 0 (initialized to 1 in JAVA)
                    int pos = 0;
                    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);
            }
        }
예제 #22
0
        public async Task InsertRowsAsync(IPersistentCollection collection, object id, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (!isInverse && RowInsertEnabled)
            {
                if (log.IsDebugEnabled())
                {
                    log.Debug("Inserting rows of collection: {0}", MessageHelper.CollectionInfoString(this, collection, id, session));
                }

                try
                {
                    // insert all the new entries
                    await(collection.PreInsertAsync(this, cancellationToken)).ConfigureAwait(false);
                    IExpectation expectation = Expectations.AppropriateExpectation(insertCheckStyle);
                    //bool callable = InsertCallable;
                    bool useBatch = expectation.CanBeBatched;
                    int  i        = 0;
                    int  count    = 0;

                    IEnumerable entries = collection.Entries(this);
                    foreach (object entry in entries)
                    {
                        if (await(collection.NeedsInsertingAsync(entry, i, elementType, cancellationToken)).ConfigureAwait(false))
                        {
                            object entryId;
                            if (!IsIdentifierAssignedByInsert)
                            {
                                // NH Different implementation: write once
                                entryId = await(PerformInsertAsync(id, collection, expectation, entry, i, useBatch, false, session, cancellationToken)).ConfigureAwait(false);
                            }
                            else
                            {
                                entryId = await(PerformInsertAsync(id, collection, entry, i, session, cancellationToken)).ConfigureAwait(false);
                            }
                            collection.AfterRowInsert(this, entry, i, entryId);
                            count++;
                        }
                        i++;
                    }

                    if (log.IsDebugEnabled())
                    {
                        log.Debug("done inserting rows: {0} inserted", count);
                    }
                }
                catch (DbException sqle)
                {
                    throw ADOExceptionHelper.Convert(sqlExceptionConverter, sqle,
                                                     "could not insert collection rows: " + MessageHelper.CollectionInfoString(this, collection, id, session));
                }
            }
        }
예제 #23
0
        protected override async Task DoExecuteBatchAsync(DbCommand ps, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            Log.Info("Executing batch");
            await(CheckReadersAsync(cancellationToken)).ConfigureAwait(false);

            if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
            {
                Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
                _currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
            }

            try
            {
                int rowCount = 0;

                if (_countOfCommands > 0)
                {
                    _currentBatch.Parameters.Clear();

                    foreach (var command in _currentBatchCommands)
                    {
                        // Batching with HANA works by simply defining multiple times each command parameter.
                        // (Undocumented feature explained by a developer of the provider.)
                        foreach (DbParameter parameter in command.Parameters)
                        {
                            _currentBatch.Parameters.Add(parameter);
                        }
                    }

                    _currentBatch.Prepare();

                    try
                    {
                        rowCount = await(_currentBatch.ExecuteNonQueryAsync(cancellationToken)).ConfigureAwait(false);
                    }
                    catch (DbException e)
                    {
                        throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
                    }
                }

                Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowCount, ps);
            }
            finally
            {
                // Cleaning up even if batched outcome is invalid
                _totalExpectedRowsAffected = 0;
                _countOfCommands           = 0;
                CloseBatchCommands();
            }
        }
예제 #24
0
        protected override async Task DoExecuteBatchAsync(DbCommand ps, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (_currentBatch != null)
            {
                int arraySize = 0;
                _countOfCommands = 0;

                Log.Info("Executing batch");
                await(CheckReadersAsync(cancellationToken)).ConfigureAwait(false);
                await(PrepareAsync(_currentBatch, cancellationToken)).ConfigureAwait(false);

                if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
                {
                    Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
                    _currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
                }

                foreach (DbParameter currentParameter in _currentBatch.Parameters)
                {
                    List <object> parameterValueArray = _parameterValueListHashTable[currentParameter.ParameterName];
                    currentParameter.Value = parameterValueArray.ToArray();
                    arraySize = parameterValueArray.Count;
                }

                // setting the ArrayBindCount on the OracleCommand
                // this value is not a part of the ADO.NET API.
                // It's and ODP implementation, so it is being set by reflection
                SetArrayBindCount(arraySize);
                try
                {
                    int rowsAffected;
                    try
                    {
                        rowsAffected = await(_currentBatch.ExecuteNonQueryAsync(cancellationToken)).ConfigureAwait(false);
                    }
                    catch (DbException e)
                    {
                        throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
                    }

                    Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowsAffected);
                }
                finally
                {
                    // Cleaning up even if batched outcome is invalid
                    _totalExpectedRowsAffected = 0;
                    _currentBatch = null;
                    _parameterValueListHashTable = null;
                }
            }
        }
예제 #25
0
        public override async Task <int> ExecuteAsync(QueryParameters parameters, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            CoordinateSharedCacheCleanup(session);

            DbCommand    st        = null;
            RowSelection selection = parameters.RowSelection;

            try
            {
                try
                {
                    CheckParametersExpectedType(parameters);                     // NH Different behavior (NH-1898)
                    // Create a copy of Parameters as ExpandDynamicFilterParameters may modify it
                    var       parameterSpecifications = Parameters.ToList();
                    var       sqlString = FilterHelper.ExpandDynamicFilterParameters(sql, parameterSpecifications, session);
                    var       sqlQueryParametersList = sqlString.GetParameters().ToList();
                    SqlType[] parameterTypes         = parameterSpecifications.GetQueryParameterTypes(sqlQueryParametersList, session.Factory);

                    st = await(session.Batcher.PrepareCommandAsync(CommandType.Text, sqlString, parameterTypes, cancellationToken)).ConfigureAwait(false);
                    foreach (var parameterSpecification in parameterSpecifications)
                    {
                        await(parameterSpecification.BindAsync(st, sqlQueryParametersList, parameters, session, cancellationToken)).ConfigureAwait(false);
                    }

                    if (selection != null)
                    {
                        if (selection.Timeout != RowSelection.NoValue)
                        {
                            st.CommandTimeout = selection.Timeout;
                        }
                    }
                    return(await(session.Batcher.ExecuteNonQueryAsync(st, cancellationToken)).ConfigureAwait(false));
                }
                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);
            }
        }
        protected override void DoExecuteBatch(IDbCommand ps)
        {
            CheckReaders();
            Prepare(_currentBatch.BatchCommand);
            if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
            {
                Factory.Settings.SqlStatementLogger.LogBatchCommand(_currentBatchCommandsLog.ToString());
                _currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
            }

            int rowsAffected;

            try
            {
                var dbProfiler = ((IDbProfiler)MiniProfiler.Current);
                if (MiniProfiler.Current == null)
                {
                    rowsAffected = _currentBatch.ExecuteNonQuery();
                }
                else
                {
                    dbProfiler.ExecuteStart(_currentBatch.BatchCommand, SqlExecuteType.NonQuery);
                    try
                    {
                        rowsAffected = _currentBatch.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        dbProfiler.OnError(_currentBatch.BatchCommand, SqlExecuteType.NonQuery, ex);
                        throw;
                    }
                    finally
                    {
                        dbProfiler.ExecuteFinish(_currentBatch.BatchCommand, SqlExecuteType.NonQuery, (DbDataReader)null);
                    }
                }
            }
            catch (DbException e)
            {
                throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
            }

            Expectations.VerifyOutcomeBatched(_totalExpectedRowsAffected, rowsAffected);

            _currentBatch.Dispose();
            _totalExpectedRowsAffected = 0;
            _currentBatch = CreateConfiguredBatch();
        }
예제 #27
0
        public override int Execute(QueryParameters parameters, ISessionImplementor session)
        {
            CoordinateSharedCacheCleanup(session);

            IDbCommand   st        = null;
            RowSelection selection = parameters.RowSelection;

            try
            {
                try
                {
                    CheckParametersExpectedType(parameters);                     // NH Different behavior (NH-1898)

                    var parameterSpecs = new HashSet <IParameterSpecification>(Parameters);
                    var sql2           = ExpandDynamicFilterParameters(sql, parameterSpecs, session);

                    var       sqlQueryParametersList = sql2.GetParameters().ToList();
                    SqlType[] parameterTypes         = parameterSpecs.GetQueryParameterTypes(sqlQueryParametersList, session.Factory);

                    st = session.Batcher.PrepareCommand(CommandType.Text, sql2, parameterTypes);
                    foreach (var parameterSpecification in parameterSpecs)
                    {
                        parameterSpecification.Bind(st, sqlQueryParametersList, parameters, session);
                    }

                    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);
            }
        }
예제 #28
0
        /// <summary>
        /// Advances the enumerator to the next element of the query results.
        /// </summary>
        /// <returns>
        /// <see langword="true" /> if the enumerator was successfully advanced to the next query results
        /// ; <see langword="false" /> if the enumerator has passed the end of the query results.
        ///</returns>
        public bool MoveNext()
        {
            bool readResult;

            try
            {
                readResult = _reader.Read();
            }
            catch (DbException e)
            {
                throw ADOExceptionHelper.Convert(_session.Factory.SQLExceptionConverter, e, "Error executing Enumerable() query",
                                                 new SqlString(_cmd.CommandText));
            }
            PostMoveNext(readResult);
            return(_hasNext);
        }
예제 #29
0
        /// <summary>
        /// Load an instance by a unique key that is not the primary key.
        /// </summary>
        /// <param name="entityName">The name of the entity to load </param>
        /// <param name="uniqueKeyPropertyName">The name of the property defining the unique key. </param>
        /// <param name="key">The unique key property value. </param>
        /// <param name="session">The originating session. </param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns> The loaded entity </returns>
        public async Task <object> LoadByUniqueKeyAsync(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ISessionFactoryImplementor factory   = session.Factory;
            IUniqueKeyLoadable         persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

            //TODO: implement caching?! proxies?!

            var keyType = GetIdentifierOrUniqueKeyType(factory)
                          // EntityUniqueKey was doing this on the type. I suspect this was needed only for its usage in Loader,
                          // which can work with entities as keys not yet instanciated and just represented by their identifiers.
                          // But since removing this call from EntityUniqueKey is done for a patch and that the code path here has
                          // no known bugs with this GetSemiResolvedType, moving its call here for avoiding altering this code
                          // path. See GH1645.
                          .GetSemiResolvedType(factory);
            EntityUniqueKey euk =
                new EntityUniqueKey(
                    entityName,
                    uniqueKeyPropertyName,
                    key,
                    keyType,
                    session.Factory);

            IPersistenceContext persistenceContext = session.PersistenceContext;

            try
            {
                object result = persistenceContext.GetEntity(euk);
                if (result == null)
                {
                    result = await(persister.LoadByUniqueKeyAsync(uniqueKeyPropertyName, key, session, cancellationToken)).ConfigureAwait(false);
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (OperationCanceledException) { throw; }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }
예제 #30
0
        protected override void DoExecuteBatch(IDbCommand ps)
        {
            if (currentBatch != null)
            {
                int arraySize = 0;
                countOfCommands = 0;

                log.Info("Executing batch");
                CheckReaders();
                Prepare(currentBatch);

                if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
                {
                    Factory.Settings.SqlStatementLogger.LogBatchCommand(currentBatchCommandsLog.ToString());
                    currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
                }

                foreach (IDataParameter currentParameter in currentBatch.Parameters)
                {
                    List <object> parameterValueArray = parameterValueListHashTable[currentParameter.ParameterName];
                    currentParameter.Value = parameterValueArray.ToArray();
                    arraySize = parameterValueArray.Count;
                }

                // setting the ArrayBindCount on the OracleCommand
                // this value is not a part of the ADO.NET API.
                // It's and ODP implementation, so it is being set by reflection
                SetObjectParam(currentBatch, "ArrayBindCount", arraySize);
                int rowsAffected;
                try
                {
                    rowsAffected = currentBatch.ExecuteNonQuery();
                }
                catch (DbException e)
                {
                    throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
                }

                Expectations.VerifyOutcomeBatched(totalExpectedRowsAffected, rowsAffected);

                totalExpectedRowsAffected = 0;
                currentBatch = null;
                parameterValueListHashTable = null;
            }
        }