-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Need help with creating NHibernate dialect for Pervasive SQL
PostPosted: Mon Mar 03, 2008 3:34 pm 
Newbie

Joined: Mon Mar 03, 2008 3:02 pm
Posts: 3
Hello.

If anybody has an experience with the creation of NHibernate driver and dialect specific to Pervasive SQL DB, please share it.

I tried for myself, but got exceptions i cannot deal with. Below i'll provide some details.

Here's my Pervasive driver implementation:
Code:
public class PervasiveClientDriver : ReflectionBasedDriver
    {
        public PervasiveClientDriver()
            : base(
            "Pervasive.Data.SqlClient",
            "Pervasive.Data.SqlClient.PsqlConnection",
            "Pervasive.Data.SqlClient.PsqlCommand")
        {
        }

        public override bool UseNamedPrefixInSql
        {
            get { return true; }
        }

        public override bool UseNamedPrefixInParameter
        {
            get { return true; }
        }

        public override string NamedPrefix
        {
            get { return "?"; }
        } 
    }


As a dialect i decided to use NHibernate.Dialect.MsSql2000Dialect.

Also, i configured NHibernate in this way:
Code:
Configuration cfg = new Configuration();
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider");
cfg.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSql2000Dialect");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "PervasiveSampling.PervasiveClientDriver, PervasiveSampling");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, "ServerDSN=DEMODATA;UID=test;PWD=test;ServerName=localhost");


My query looks like:
Code:
IQuery query = session.CreateQuery("select p from Person as p where p.FirstName = 'James'");


At runtime i got the following exception:
Code:
2008-03-03 21:04:13,984 [232] NHibernate.Loader.Loader.GetResultSet(:0) - SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?p0
2008-03-03 21:04:13,984 [232] NHibernate.Impl.BatcherImpl.LogCommand(:0) - SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?p0; ?p0 = '104101361'
2008-03-03 21:04:14,031 [232] NHibernate.Util.ADOExceptionReporter.LogExceptions(:0) - SQL Exception
Pervasive.Data.SqlClient.PsqlException: Pervasive.Data.SqlClient.Lna.LnaException: [LNA][Pervasive][ODBC Engine Interface]Syntax Error: SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?p<< ??? >>0
   at Pervasive.Data.SqlClient.Lna.LnaStatement.ExecDirect(String sql, ParamInfoSet pis, ColumnInfoSet cis, ParamDescSet pds)
   at Pervasive.Data.SqlClient.PsqlCommand.Execute(Boolean parseOnly, CommandBehavior behavior, Boolean needReader)
   at Pervasive.Data.SqlClient.PsqlCommand.ExecuteReader(CommandBehavior behavior)
   at Pervasive.Data.SqlClient.PsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at NHibernate.Impl.BatcherImpl.ExecuteReader(IDbCommand cmd)
   at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, RowSelection selection, ISessionImplementor session)
2008-03-03 21:04:14,046 [232] NHibernate.Util.ADOExceptionReporter.LogExceptions(:0) - Pervasive.Data.SqlClient.PsqlException: Pervasive.Data.SqlClient.Lna.LnaException: [LNA][Pervasive][ODBC Engine Interface]Syntax Error: SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?p<< ??? >>0
   at Pervasive.Data.SqlClient.Lna.LnaStatement.ExecDirect(String sql, ParamInfoSet pis, ColumnInfoSet cis, ParamDescSet pds)
   at Pervasive.Data.SqlClient.PsqlCommand.Execute(Boolean parseOnly, CommandBehavior behavior, Boolean needReader)
   at Pervasive.Data.SqlClient.PsqlCommand.ExecuteReader(CommandBehavior behavior)
   at Pervasive.Data.SqlClient.PsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at NHibernate.Impl.BatcherImpl.ExecuteReader(IDbCommand cmd)
   at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, RowSelection selection, ISessionImplementor session)


Moreover, when i used the following configuration:
Code:
Configuration cfg = new Configuration();
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider");
cfg.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSql2000Dialect");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.OdbcDriver");
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString,
    "Driver={Pervasive ODBC Client Interface};ServerDSN=DEMODATA;ServerName=localhost;UID=test;PWD=test");


everything worked just fine, and through the logs i saw this SQL has been generated:
Code:
2008-03-03 21:23:38,421 [2460] NHibernate.Impl.BatcherImpl.Generate(:0) - Building an IDbCommand object for the SqlString: SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?
2008-03-03 21:23:38,421 [2460] NHibernate.Type.NullableType.NullSafeSet(:0) - binding '104101361' to parameter: 0
2008-03-03 21:23:38,421 [2460] NHibernate.Loader.Loader.GetResultSet(:0) - SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?
2008-03-03 21:23:38,421 [2460] NHibernate.Impl.BatcherImpl.LogCommand(:0) - SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?; p0 = '104101361'

After careful revision of two SQLs we can note the difference:
Code:
SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?p0; ?p0 = '104101361'

versus
Code:
SELECT person0_.Id as Id0_0_, person0_.First_Name as First2_0_0_ FROM Person person0_ WHERE person0_.Id=?; p0 = '104101361'


Both SQLs are not processed through the Pervasive.SQL Control Center's SQL Editor.

I would be very grateful for any help.

Thanks in advance.

P.S. Sorry for long post.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 03, 2008 7:57 pm 
Newbie

Joined: Mon Mar 03, 2008 3:02 pm
Posts: 3
I've resolved the issue. Here's updated driver implementation:
Code:
public class PervasiveClientDriver : ReflectionBasedDriver, ISqlParameterFormatter
    {
        public PervasiveClientDriver()
            : base(
            "Pervasive.Data.SqlClient",
            "Pervasive.Data.SqlClient.PsqlConnection",
            "Pervasive.Data.SqlClient.PsqlCommand")
        {
        }

        public override bool UseNamedPrefixInSql
        {
            get { return true; }
        }

        public override bool UseNamedPrefixInParameter
        {
            get { return true; }
        }

        public override string NamedPrefix
        {
            get { return "?"; }
        }

        string ISqlParameterFormatter.GetParameterName(int index)
        {
            return "?";
        }

        public override bool SupportsMultipleOpenReaders
        {
            get { return false; }
        }
    }


I used NHibernate.Dialect.MsSql2000Dialect dialect.


Top
 Profile  
 
 Post subject: Re: Need help with creating NHibernate dialect for Pervasive SQL
PostPosted: Fri May 07, 2010 11:55 pm 
Newbie

Joined: Fri May 07, 2010 11:49 pm
Posts: 1
I know this post is quite old but curious if you've had any other problems / issues using Pervasive.


Top
 Profile  
 
 Post subject: Re: Need help with creating NHibernate dialect for Pervasive SQL
PostPosted: Wed Jul 14, 2010 1:03 pm 
Newbie

Joined: Wed Jul 14, 2010 11:55 am
Posts: 1
I've been working with getting NHibernate to work with Pervasive over the past couple of days and finally got something that works. The posted solution appears not to work due to the named prefixes option in the driver. I changed my custom driver settings as follows:

Code:
      public override bool UseNamedPrefixInSql
      {
         get { return false; }
      }

      public override bool UseNamedPrefixInParameter
      {
         get { return false; }
      }


I had to set this to false, because pervasive depends on the order or parameters and doesn't support naming them in select/insert statements. From Pervasive's documentation:

    Parameter Markers
    Parameter markers, including parameter markers for stored procedures, are specified in the Pervasive PSQL data provider by using the "?" symbol in SQL statements.

    UPDATE emp SET job = ?, sal = ? WHERE empno = ?

    Because parameters are not named, the bindings must occur in the order of the parameters in the statement. This means that the calls to the Add() method on the PsqlParameterCollection object (adding the Parameter objects to the collection) must occur in the order of the "?"s in the command text.

I also chose to implement my own dialect instead of trying to use one of the existing ones that's "close". The main reason was so that I could specify all the propper data types to generate the db schema using something like this:

Code:
   NHibernate.Tool.hbm2ddl.SchemaExport SE = new NHibernate.Tool.hbm2ddl.SchemaExport ( DbConfig );
   SE.SetOutputFile ( "DbSchema.sql" );
   SE.Execute ( true, true, false );


Where the DbConfig is an NHibernate Configuration object that's be configured. Here's my custom Dialect class for pervasive:

Code:
   /// <summary>Specific SQL dialect for a Pervasive v10 or greater db engine</summary>
   public class PsqlDialect : NHibernate.Dialect.Dialect
   {

      /// <summary>Default constructor</summary>
      public PsqlDialect ()
      {

         // string types
         RegisterColumnType ( DbType.AnsiStringFixedLength, "CHAR(255)" );
         RegisterColumnType ( DbType.AnsiStringFixedLength, 8000, "CHAR($l)" );
         RegisterColumnType ( DbType.AnsiStringFixedLength, 2147483647, "LONGVARCHAR" );
         RegisterColumnType ( DbType.AnsiString, "VARCHAR(255)" );
         RegisterColumnType ( DbType.AnsiString, 8000, "VARCHAR($l)" );
         RegisterColumnType ( DbType.AnsiString, 2147483647, "LONGVARCHAR" );
         RegisterColumnType ( DbType.StringFixedLength, "CHAR(255)" );
         RegisterColumnType ( DbType.StringFixedLength, 8000, "CHAR($l)" );
         RegisterColumnType ( DbType.StringFixedLength, 2147483647, "LONGVARCHAR" );
         RegisterColumnType ( DbType.String, "VARCHAR(255)" );
         RegisterColumnType ( DbType.String, 8000, "VARCHAR($l)" );
         RegisterColumnType ( DbType.String, 2147483647, "LONGVARCHAR" );

         // numeric data types
         RegisterColumnType ( DbType.Boolean, "BIT" );
         RegisterColumnType ( DbType.Byte, "UTINYINT" );
         RegisterColumnType ( DbType.SByte, "TINYINT" );
         RegisterColumnType ( DbType.UInt16, "USMALLINT" );
         RegisterColumnType ( DbType.Int16, "SMALLINT" );
         RegisterColumnType ( DbType.UInt32, "UINTEGER" );
         RegisterColumnType ( DbType.Int32, "INTEGER" );
         RegisterColumnType ( DbType.UInt64, "UBIGINT" );
         RegisterColumnType ( DbType.Int64, "BIGINT" );
         RegisterColumnType ( DbType.Single, "REAL" );
         RegisterColumnType ( DbType.Double, "DOUBLE" );
         RegisterColumnType ( DbType.Currency, "CURRENCY" );
         RegisterColumnType ( DbType.Decimal, "DECIMAL(19,5)" );
         RegisterColumnType ( DbType.Decimal, 19, "NUMERIC($p, $s)" );

         // date/time data types
         RegisterColumnType ( DbType.Date, "DATE" );
         RegisterColumnType ( DbType.DateTime, "TIMESTAMP" );
         RegisterColumnType ( DbType.Time, "TIME" );

         // binary types
         RegisterColumnType ( DbType.Binary, "LONGVARBINARY" );
         RegisterColumnType ( DbType.Binary, 8000, "BINARY" );

         // other data types
         RegisterColumnType ( DbType.Guid, "UNIQUEIDENTIFIER" );

         DefaultProperties[Environment.ConnectionDriver] = "Db.Driver.PsqlDataDriver";

      }

      /// <summary>(Ture) Adding support for the identity column</summary>
      public override bool SupportsIdentityColumns
      {
         get { return true; }
      }

      /// <summary>Get the selection string to retrieve the last generated identity</summary>
      public override string IdentitySelectString
      {
         get { return "SELECT @@IDENTITY"; }
      }

      /// <summary>Get the column data type string for an identity column</summary>
      public override string IdentityColumnString
      {
         get { return "IDENTITY"; }
      }

      /// <summary>Overriden to support proper creation of identity columns</summary>
      public override bool HasDataTypeInIdentityColumn
      {
         get { return false; }
      }

      /// <summary>Grammar portion in an alter table for adding a column</summary>
      public override string AddColumnString
      {
         get { return "add column"; }
      }

      /// <summary>Index names don't need to be qualified</summary>
      public override bool QualifyIndexName
      {
         get { return false; }
      }

      /// <summary>TODO: Need to add support for retrieving the database schema from Pervasive</summary>
      /// <param name="connection"></param>
      /// <returns>Null</returns>
      public override IDataBaseSchema GetDataBaseSchema ( DbConnection connection )
      {
         throw new NotSupportedException ( "Retrieving the database schema is currently unsupported for Pervasive" );
      }

      /// <summary>The syntax used to drop a primary key constraint from a table.</summary>
      /// <param name="constraintName">The name of the primary key to drop (unused by Pervasive).</param>
      /// <returns>The SQL string "drop primary key".</returns>
      public override string GetDropPrimaryKeyConstraintString ( string constraintName )
      {
         return " drop primary key";
      }

      /// <summary>(True) Support for temporary tables exists with some limitations to full tables</summary>
      public override bool SupportsTemporaryTables
      {
         get { return true; }
      }

      /// <summary>Generates a temporary table by prepending a '#' symbol. This
      /// represents a "local" temporary table, and global temporary tables can be
      /// created using two precending '##' symbols</summary>
      /// <param name="baseTableName">the base name for the table</param>
      /// <returns>#(baseTableName)</returns>
      public override string GenerateTemporaryTableName ( string baseTableName )
      {
         return "#" + baseTableName;
      }

   }


Top
 Profile  
 
 Post subject: Re: Need help with creating NHibernate dialect for Pervasive SQL
PostPosted: Wed Aug 18, 2010 3:11 am 
Newbie

Joined: Wed Aug 18, 2010 2:53 am
Posts: 1
Thanks dbgnome.

When I find the time I will have a go with this one.

The Pervasive syntax for querying pervasive seems not very different from for instance Sql Server. But there seem to be quite some differences in syntax for creating database schemas. Is that a problem for your solution? Is there some overview available of differences?

Koob.


Top
 Profile  
 
 Post subject: Re: Need help with creating NHibernate dialect for Pervasive SQL
PostPosted: Sun Dec 19, 2010 3:01 am 
Newbie

Joined: Sun Dec 19, 2010 2:57 am
Posts: 1
Yeah, ofcourse it works for me, however the UDF does some very CPU intensive calculations and the only reason I went with this whole SQL/UDF approach is to reduce overhead and speed up my APP that was already working correctly. If I call the UDF twice, I'll only make the APP slower defeating the purpose of this entire venture.

I see what you are doing and I see how it is working for you. However, I need the results returned and I also need to sort based on them. It works great with regular SQL query, but Hibernate fails to maintain the proper alias that I assign.

_________________
hotels
cheap flights
sunglasses
digital cameras
handbags


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.