// Copyright © 2002 - 2007 DataDirect Technologies Corp. All Rights Reserved.
using System;
using System.Data;
using System.Data.Common;
using System.Security.Permissions;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;
using Pervasive.Data.SqlClient;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace DDTek.EnterpriseLibrary.Data.Pervasive {

	[PsqlPermission(SecurityAction.Demand)]
#if ENTLIB41
	[DatabaseAssembler(typeof(PsqlDatabaseAssembler))]
#endif
    public class PsqlDatabase : Database {

		/// <summary> Footprint information field.
		/// </summary>
		internal const string footprint = "$Revision$";

		/// <summary>
		/// Initializes a new instance of the <see cref="PsqlDatabase"/> class with a connection string.
		/// </summary>
		/// <param name="connectionString">The connection string.</param>
		public PsqlDatabase(string connectionString)
            : base(connectionString, PsqlFactory.Instance)
        {

		}

		protected override void DeriveParameters(DbCommand discoveryCommand) {

            PsqlCommandBuilder.DeriveParameters((PsqlCommand)discoveryCommand);
		}

		/// <summary>
		/// Returns the starting index for parameters in a command.
		/// </summary>
		/// <returns>The starting index for parameters in a command.</returns>
		protected override int UserParametersStartIndex() {

			return 1;
		}

		/// <devdoc>
		/// Listens for the RowUpdate event on a dataadapter to support UpdateBehavior.Continue
		/// </devdoc>
        private void OnPsqlRowUpdated(object sender, PsqlRowUpdatedEventArgs rowThatCouldNotBeWritten)
        {

			if (rowThatCouldNotBeWritten.RecordsAffected == 0) {

				if (rowThatCouldNotBeWritten.Errors != null) {

					rowThatCouldNotBeWritten.Row.RowError = Resources.ExceptionMessageUpdateDataSetRowFailure;
					rowThatCouldNotBeWritten.Status = UpdateStatus.SkipCurrentRow;
				}
			}
		}

		/// <summary>
		/// Sets the RowUpdated event for the data adapter.
		/// </summary>
		/// <param name="adapter">The <see cref="DbDataAdapter"/> to set the event.</param>
		protected override void SetUpRowUpdatedEvent(DbDataAdapter adapter) {

			((PsqlDataAdapter)adapter).RowUpdated += new PsqlRowUpdatedEventHandler(OnPsqlRowUpdated);
		}

		/// <summary>
		/// Determines if the number of parameters in the command matches the array of parameter values.
		/// </summary>
		/// <param name="command">The <see cref="DbCommand"/> containing the parameters.</param>
		/// <param name="values">The array of parameter values.</param>
		/// <returns><see langword="true"/> if the number of parameters and values match; otherwise, <see langword="false"/>.</returns>
		protected override bool SameNumberOfParametersAndValues(DbCommand command, object[] values) {

			// Psql procedures have an implicit return value that DeriveParameters will include
			int returnParameterCount = 1;
			int numberOfParametersToStoredProcedure = command.Parameters.Count - returnParameterCount;
			int numberOfValuesProvidedForStoredProcedure = values.Length;

			return (numberOfParametersToStoredProcedure == numberOfValuesProvidedForStoredProcedure);
		}
	}
}
