GithubHelp home page GithubHelp logo

dataaction / adonetcore.aseclient Goto Github PK

View Code? Open in Web Editor NEW
105.0 19.0 43.0 1.09 MB

AdoNetCore.AseClient - a .NET Core DB Provider for SAP ASE

License: Apache License 2.0

C# 100.00%
ase ado-net dbprovider driver sybase sap netcore netcore2 tds connectionstrings

adonetcore.aseclient's People

Contributors

anat0li avatar bbarry avatar c-j-hughes avatar chgeuer avatar driseley avatar formicas avatar gitter-badger avatar kaltalen avatar kdcllc avatar ngvtien avatar northcode avatar senseibaka avatar sgwyn avatar ssmkittel avatar valente500 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adonetcore.aseclient's Issues

[linq2db] AseDataReader returns decimal? type from GetFieldType(i)

Query

SELECT TOP 1
	Convert(Decimal(29,10), @value1) as [c1]
FROM
	[LinqDataTypes] [t1]

parameter type is Decimal with value 6579.64648m

Native provider returns decimal type, managed provider returns decimal? type.

It is funny that it was discovered only becase we had bug in our code that didn't allowed us to process Nullable types properly in some cases.

linq2db test: ConvertTests.ConvertFromOneToAnother.LinqService

Trying to set textsize

Hi,

I am trying to set the text size if both the connection string and in code, as seen below:

Data Source='***';Port='***';UID='***';Pwd='***';Database='***';Charset='iso_1';Pooling=True;Min Pool Size=10;Application Name='***';TextSize=2147483647;ConnectionIdleTimeout=240

`
using (var connection = new AseConnection(_dbConnectionStringFactory.GetConnectionString()))
{
await connection.OpenAsync();

            using (var command = connection.CreateCommand())
            {
                command.CommandText = @"
                            SET TEXTSIZE 2147483647 
                            SELECT DocumentSchemaID, AlgorithmRevisionGuidIDF, RevisionPayloadTXT 
                            FROM AlgorithmSnapshot
                            WHERE AlgorithmRevisionGuidIDF='" + revisionGuid + "'";

                using (var reader = command.ExecuteReader())
                {
                    // Get the results.
                    while (reader.Read())
                    {
                        var snapshot = new AlgorithmSnapshot();
                        snapshot.DocumentSchemaID = Convert.ToInt32(reader.GetString(0));
                        snapshot.AlgorithmRevisionGuidIDF = reader.GetString(1);
                        snapshot.RevisionPayloadTXT = reader.GetString(2);
                        return snapshot;
                    }
                }
            }
        }

`

But the data coming back in the payload is still getting truncated to the default 13k or so. Am I doing something wrong, or is there an issue?

Thanks,
Andrew

Dispose(bool) should not throw if called more than once

https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern

โœ“ DO allow the Dispose(bool) method to be called more than once. The method might choose to do nothing after the first call.

X AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).

bugs:

throw new ObjectDisposedException(nameof(AseTransaction));

(also base.Dispose(disposing) should be called immediately at the start of the method instead of inside that if)

throw new ObjectDisposedException(nameof(AseCommand));

throw new ObjectDisposedException(nameof(AseConnection));

The general method for overriding dispose should look like this:

protected override void Dispose(bool disposing)
{
    base.Dispose(disposing);
    if (_isDisposed) return;
    if (disposing)
    {
        // clean up
    }
    _isDisposed = true;        
}

(DbConnection for example will call an event handler for an EventDisposed component event during disposal that the implementation here doesn't)

Additionally there are minor semantic differences between this driver and the SAP driver in that this driver throws ObjectDisposedException in methods of AseConnection after you have disposed where the SAP driver does not (though the SAP driver often doesn't do what you intend in these circumstances and probably should). For example you can add and remove handlers to InfoMessage after disposing with the SAP driver.

The guidelines for the dispose pattern also state:

โœ“ CONSIDER providing method Close(), in addition to the Dispose(), if close is standard terminology in the area.

When doing so, it is important that you make the Close implementation identical to Dispose and consider implementing the IDisposable.Dispose method explicitly.

But that would require a larger semantic difference between this driver and the SAP one... honestly I think the SAP driver is riddled with bugs surrounding Close and Dispose and would prefer stricter adherence to the design guidelines.

Text or varchar length problem

When executing queries resulting in rows containing text or varchar populated fields, I've an error due to an incorrect calculated length of the stream that follows, containing the value (string).

I'm using Sybase 12.0.1 (ASA 12).
When executing query in the ValueReader.cs switch, when I reach
var textPtrLen = (byte)stream.ReadByte();
for TdsDataType.TDS_TEXT and TDS_VARCHAR it results always in 0 (textPtrLen = 0).

If I skip 1 byte textPtrLen will have the correct value. I've patched the library for testing purpose in this way
(byte)stream.ReadByte();
var textPtrLen = (byte)stream.ReadByte();

and all query now results in rows correctly populated.

Is this a bug of AseClient library? ... or did I miss something?

Support NamedParameters = false

SAPs AseClient allows AseCommands to be executed like the following:

  • SELECT * FROM myTable WHERE myColumn = ?
  • SELECT * FROM myTable WHERE myColumn = @myColumn

We support the latter syntax, but not the former.

To place the AseCommand in the former mode, either it or the owning AseConnection can have their NamedParameters property set to false.

We should add this support.

[linq2db] ArgumentException : Cannot change internal connection state as it is Broken

This error generated by next test after failure from #48, so I think it should be fixed prior to #48 while it should be easy to reproduce.
Second test do following query:

Assert.That(conn.Execute<string>     ("SELECT '<xml/>'"),            Is.EqualTo("<xml/>"));
Result StackTrace:	
at AdoNetCore.AseClient.Internal.ConnectionPool.Reserve()
   at AdoNetCore.AseClient.Internal.ConnectionPoolManager.Reserve(String connectionString, IConnectionParameters parameters)
   at AdoNetCore.AseClient.AseConnection.Open()
   at LinqToDB.Data.DataConnection.get_Connection() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 883
   at LinqToDB.Data.DataConnection.CreateCommand() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 979
   at LinqToDB.Data.DataConnection.get_Command() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 970
   at LinqToDB.DataProvider.DataProviderBase.InitCommand(DataConnection dataConnection, CommandType commandType, String commandText, DataParameter[] parameters) in c:\GitHub\linq2db.work\Source\LinqToDB\DataProvider\DataProviderBase.cs:line 104
   at LinqToDB.Data.DataConnection.InitCommand(CommandType commandType, String sql, DataParameter[] parameters, List`1 queryHints) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 950
   at LinqToDB.Data.CommandInfo.Execute[T]() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\CommandInfo.cs:line 549
   at LinqToDB.Data.DataConnectionExtensions.Execute[T](DataConnection connection, String sql) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnectionExtensions.cs:line 1069
   at Tests.DataProvider.SybaseTests.TestXml(String context) in c:\GitHub\linq2db.work\Tests\Linq\DataProvider\SybaseTests.cs:line 422
--ArgumentException
   at AdoNetCore.AseClient.Internal.InternalConnection.SetState(InternalConnectionState newState)
   at AdoNetCore.AseClient.Internal.InternalConnection.set_IsDoomed(Boolean value)
   at AdoNetCore.AseClient.Internal.InternalConnection.Ping()
   at AdoNetCore.AseClient.Internal.ConnectionPool.FetchIdlePooledConnection()
   at AdoNetCore.AseClient.Internal.ConnectionPool.<ReservePooledConnection>d__13.MoveNext()
Result Message:	
AdoNetCore.AseClient.AseException : No message provided
  ----> System.ArgumentException : Cannot change internal connection state as it is Broken

linq2db test: SybaseTests.TestTimeSpan + SybaseTests.TestXml

Add ASEClientFactory to other versions of framework besides .net core 2.1

Is there a specific reason why the client factory class cannot be added to the other supported .net versions?

Specifically .NET Standard 2.0, .NET Core 2.0, .NET 4.6. I understand why it wouldn't be added to .net core 1.0/1.1 the full ADO.NET System.Data/System.Data.Common API wasn't completely realized until .NET standard 2.0.

If not I can help with this effort.

Selecting a calculated decimal value causes a break in the client

Can be reproduced with the following sample:

declare @a decimal(21,6), @b decimal(9,4)
set @a = 1000
set @b = 0.05

select (@a * @b)/100

The resulting value is sent over the wire to the client as a decimal (42, 21), represented in 18 bytes (+1 byte for sign). The client falls-over trying to interpret this value.

[linq2db] Different handling of \u2000 (and probably \u2001) character by native and managed providers

It is a bit strange issue, because native provider also do strange things with those characters for some reason.

table column: ncharDataType nchar(20) NULL

Test inserts string and then read it back and compare.

Test have issue with following two characters: \u2000 and \u2001
https://www.fileformat.info/info/unicode/char/2000/index.htm
https://www.fileformat.info/info/unicode/char/2002/index.htm

For native provider we receive decomposition of those characters: \2002 and \u2003
For managed provider we receive \u20 (space), which is also correct replacement.

Not sure how it should be fixed or should it be fixed at all, as from my PoV, database/provider shouldn't apply unicode normalization rules.

linq2db test: CharTypesTests.CharTrimming

[linq2db] Error "The parameter of type 49 did not have a valid value"

Error: AseException: The parameter of type 49 did not have a valid value.

Query:

INSERT INTO [TestMerge2]
(
	[Id],
	[Field1],
	[FieldInt64],
	[FieldString],
	[FieldNString],
	[FieldChar],
	[FieldNChar],
	[FieldFloat],
	[FieldDouble],
	[FieldDateTime],
	[FieldBinary],
	[FieldGuid],
	[FieldDecimal],
	[FieldDate],
	[FieldTime],
	[FieldEnumString],
	[FieldEnumNumber]
)
VALUES
(
	@Id,
	@FieldInt32,
	@FieldInt64,
	@FieldString,
	@FieldNString,
	@FieldChar,
	@FieldNChar,
	@FieldFloat,
	@FieldDouble,
	@FieldDateTime,
	@FieldBinary,
	@FieldGuid,
	@FieldDecimal,
	@FieldDate,
	@FieldTime,
	@FieldEnumString,
	@FieldEnumNumber
)

Table:

CREATE TABLE TestMerge2
(
	Id     int NOT NULL,
	Field1 int NULL,
	Field2 int NULL,
	Field3 int NULL,
	Field4 int NULL,
	Field5 int NULL,

	FieldInt64      BIGINT            NULL,
	FieldString     VARCHAR(20)       NULL,
	FieldNString    NVARCHAR(20)      NULL,
	FieldChar       CHAR(1)           NULL,
	FieldNChar      NCHAR(1)          NULL,
	FieldFloat      REAL              NULL,
	FieldDouble     FLOAT             NULL,
	FieldDateTime   DATETIME          NULL,
	FieldBinary     VARBINARY(20)     NULL,
	FieldGuid       CHAR(36)          NULL,
	FieldDecimal    DECIMAL(24, 10)   NULL,
	FieldDate       DATE              NULL,
	FieldTime       TIME              NULL,
	FieldEnumString VARCHAR(20)       NULL,
	FieldEnumNumber INT               NULL,

	CONSTRAINT PK_TestMerge2 PRIMARY KEY CLUSTERED (Id)
)

As I understant, 49 is TDS_DATE

@FieldDate parameter has value {23-11-3210 00:00:00}

linq2db test: MergeTests.TestMergeTypes

Discrepancy in handling of null vs zero-length strings

Due to the nature of the TDS protocol, there is no difference between null and a zero-length string.

This is because strings are transmitted as length-prefixed, with no separate bit to signal a null value.

So, null is transmitted as "this string is 0 bytes long"
and, empty is transmitted as "this string is 0 bytes long".

Therefore, ASE interprets "this string is 0 bytes long" as null, regardless of the caller's intent.

Currently, our driver doesn't make the distinction between the two, which can result in insertion errors ("Attempt to insert null value into column 'foo'").


The SAP Driver has the following Ribo output:

PARAMFMT Token (0xEC); variable length.
  ...
  Param 1
    User Type [4]:              0
    Data Type [1]:              CHAR
    Length [1]:                 255
    Locale Length [1]:          0
PARAMS Token (0xD7); variable length.
  Param 1
    Length [1]:                 1
    Param data [1]:             " " (0x20)

So as can be seen, to skirt this issue we should send zero-length strings as single spaces.

Corollary: look at what the SAP driver does to these values when they're being read out. Does the driver receive a single space and interpret it as string.Empty?

AseConnection is missing public static method ClearPools

Sybase.Data.AseClient.AseConnection has a method:

public static void ClearPools() which loops over all the pools in the connection pool manager and calls clear on them.

I'm not sure it should be implemented but the lack of this method does cause errors for people using it.

Code Access Security is deprecated

According to this, and this, CAS is no longer recommended.

CoreFX has taken the approach of supporting the CAS types, but with stub implementations. That way code that depends on these types will still compile. We should do the same for AseClientPermission and AseClientPermissionAttribute.

Support AseDecimal

AseDecimal represents a decimal or numeric number with a maximum precision of 38.

The SAP AseClient provides an implementation of this type which we'd like to replicate.

Microsoft provides an equivalent implementation for the SqlClient - SqlDecimal - which could be a reference point.

ASE docs here

If implemented, the corresponding GetAseDecimal(int ordinal) method should be implemented on the AseDataReader class.

Column aliases not appearing in result set

When performing a query like this:

select some_column as some_alias from some_table

The result set uses some_column as the column name, instead of some_alias.

TDS_ROWFMT2 contains a column_label field, which is representative of the alias, if it exists.

We should give preference to the alias, and then to the underlying column name.

Getting timeout when trying to connect

When I try to open a new connection, I get the following error:

AseException: Timed out trying to establish a connection
AdoNetCore.AseClient.Internal.ConnectionPool.Reserve()

Could I be doing something wrong? My code looks like:

using (var test = new AseConnection("Data Source=sybase;Port=5000;Database=gravity;Uid=sa;Pwd=myPassword;pooling=false;"))
{
    test.Open(); // Blows up here
    test.ExecuteScalar<int>("Select (1)");
 }

I know my server is running because I can connect to it with DBeaver.

AseConnection.InfoMessage is currently never triggered

When I issue the following command to an ASE

LOAD DATABASE AZU WITH LISTONLY=LOAD_SQL,UNTIL_TIME='2018-08-16T17:40:23:310'

it returns a SQL script which I could use to restore a database to a particular point in time. The problem is that the response is not a result set or so, but just informational messages.

I subscribed to AseConnection.InfoMessage, but the private AseConnection.NotifyInfoMessage() method is never triggered... The event InfoMessageInternal has a TODO flag :-).

What would be the best / desired way to implement that functionality? InternalConnection.InternalExecuteAsync() looks like a place where the command.Connection could be passed down to the MessageTokenHandler to fire this event.

[linq2db] InvalidCastException reading value of Time parameter

Error: Specified cast is not valid. Parameter: @p. From: DateTime to: TimeSpan

test code:

var time = new TimeSpan(12, 12, 12);
Assert.That(conn.Execute<TimeSpan> ("SELECT @p", DataParameter.Time  ("p", time)),              Is.EqualTo(time));

stack:

SET     @p = '1900-01-01 12:12:12'

SELECT @p

DataConnection: Error
Exception: System.InvalidCastException
Message  : Specified cast is not valid. Parameter: @p. From: DateTime to: TimeSpan
   at AdoNetCore.AseClient.Internal.ValueWriter.Cast[T](Object value, FormatItem format)
   at AdoNetCore.AseClient.Internal.ValueWriter.Write(Object value, Stream stream, FormatItem format, Encoding enc)
   at AdoNetCore.AseClient.Token.ParametersToken.Write(Stream stream, DbEnvironment env)
   at AdoNetCore.AseClient.Packet.NormalPacket.Write(Stream stream, DbEnvironment env)
   at AdoNetCore.AseClient.Internal.RegularSocket.SendPacket(IPacket packet, DbEnvironment env)
   at AdoNetCore.AseClient.Internal.InternalConnection.SendPacket(IPacket packet)
   at AdoNetCore.AseClient.Internal.InternalConnection.InternalExecuteAsync(AseCommand command, AseTransaction transaction, TaskCompletionSource`1 rowsAffectedSource, TaskCompletionSource`1 readerSource, CommandBehavior behavior)
--- End of stack trace from previous location where exception was thrown ---
   at AdoNetCore.AseClient.Internal.InternalConnection.ExecuteReader(CommandBehavior behavior, AseCommand command, AseTransaction transaction)
   at AdoNetCore.AseClient.AseCommand.ExecuteReader(CommandBehavior behavior)
   at AdoNetCore.AseClient.AseCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at LinqToDB.Data.DataConnection.ExecuteReader(CommandBehavior commandBehavior) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 1138

linq2db test: SybaseTests.TestTimeSpan

Multiple issues

Hello

I'm currently working on adding support for this provider to linq2db library (linq2db/linq2db#1159).

We have a lot of tests for native provider already and reuse them for your provider. While all those tests pass for native provider, for this provider we have a lot of failing tests.

Should I add separate issue for each failure or we can have this as meta-issue and work together on them?
Also we can discuss stuff in Slack to make communication more productive.

Severity not handled properly when talking to Backup Server

When issuing dump&load commands, according to the ASE 16 documentation, the ASE backup server returns the severity of a message inline with the text, for example in a message like

Backup Server: 4.172.1.4: The value of 'allocated pages threshold' has been set to 40 %.

In that tuple 4.172.1.4, the severity is 1 which means an informational value from the backup server. Values 2, 3 and 4 mean 'unexpected conditions'.

Even if the backup server indicates an error (severity > 1), the "outer" severity might be less than 10, so that the check

is not correct.

Can data reader only handle a single table?

I return multiple tables from a query... but can not seem to be able to iterate over the tables.
Is there something I need to do to get the next table.

Expect to be able to load each table returned into object then go to next table.

Implement the EncryptPassword connection parameter

I can connect to a SAP database using the following command line:

isql64 -U<user> -S<app> -X

I am trying to convert that to a connection string and I think I can translate -S to ApplicationName but -X is a problem because, apparently, EncryptPassword doesn't do anythong and the login fails.

AnsiStringFixedLength output parameter null

When executing a stored procedure with a parameter with the following properties:

p.DbType = DbType.AnsiStringFixedLength;
p.Direction = ParameterDirection.Output;

After execution, p.Value is null, even when the procedure sets the value.

The workaround is to specify p.Size = some_appropriate_value;


The SAP driver does not experience this issue.
Judging by the output of Ribo, the SAP driver sets Size to 255, regardless of what the user dictates:

Status [1]:                 PARAM_RETURN (0x01)
User Type [4]:              0
Data Type [1]:              CHAR
Length [1]:                 255

By comparison, we send:

Status [1]:                 PARAM_RETURN (0x01)
User Type [4]:              0
Data Type [1]:              VARCHAR
Length [1]:                 0

Prevent SQL injection

String values can contain special SQL characters like single quotes that can be use to perform SQL injection. Ensure these are escaped when using parameterised commands.

EnvChangeTokenHandler can prevent connections if Encoding.GetEncoding() fails

Currently, EnvChangeTokenHandler.CharsetMap is a dictionary of string -> Encoding.

If Encoding.GetEncoding cannot locate the specified encoding scheme (regardless of if it will be used), then construction of the dictionary fails, preventing driver usage.

To allow for more obscure character encodings to be added without breaking existing function, this dictionary should change to string -> Func<Encoding>

Fixed-length-string padding -- should we add an option to auto-TrimEnd()?

By default, the driver reports strings to the caller exactly as the database has supplied them.

That's normally fine, but in the case of fixed-length-strings (seems to occur quite frequently in legacy databases...) this may mean that the caller needs to scatter some .TrimEnd()s around the place, or come up with some wrapper over ado.net to sanitize data before using it.

Is it worth us adding an option to the driver to auto-trim padded strings before returning them to the caller?
Assuming there are other similar quality-of-life improvements that could be made, is there a solid case for/against the driver implementing them?

[linq2db] NULL value of image type returned as empty

Following query returns null for native provider and byte[0] for managed:

Assert.That(conn.Execute<byte[]>("SELECT Cast(NULL as image)"),           Is.EqualTo(null));

linq2db test (for tracking): SybaseTests.TestBinary

DataSet compatibility (.net core 2.0)

A lot of our testing has revolved around using Dapper, or just the plain old AseDataReader.
There is also the option of using System.Data.DataSet.

We should add tests revolving around the use of DataSet, and then fix any emergent bugs. Maybe start with DataSet.Load.

Implement prepared statements

The IDbCommand and DbCommand types define a method Prepare that implementers are required to implement.

The intention is that this command instructs the server to compile the query so that repeated executions are faster.

Our current implementation is a no-op. We should consider implementing this.

Expose AseCommand empty parameter constructor

The AseParameter classe is exposing only the overload that receives an AseConnection parameter that is needed if you want to use the provider with NHibernate.

Trying to use this overload, but passing null throws a NullRefenceException on this line.

Can you expose the empty parameter constructor (it is internal now) and make the NamedParamters on this line property true in this case?

Drop-in contract mismatches

To improve the drop-in-replacement nature of this library, the following items need to be implemented or at least stubbed:

AseConnection

public void ClearPool()
public object Clone() // ICloneable
public bool IsCaseSensitive()
public IDictionary RetrieveStatistics()
public bool StatisticsEnabled { get; set; }
public AseTransaction Transaction { get; }

AseCommand

public string GetDataTypeName(int colindex)
public object Clone() // ICloneable
public void ResetCommandTimeout()
public XmlReader ExecuteXmlReader()

AseDataReader

public IList GetList()
public bool ContainsListCollection { get; }

AseError

public void Dispose() // IDisposable

AseErrorCollection

public object SyncRoot { get; }
public bool IsSynchronized { get; }

AseParameter

public object Clone() // ICloneable

AseTransaction

public AseConnection AseConnection

[linq2db] DbConnection.GetSchema API support

Right now this API is not implemented and throws NotSupportedException from base class.

linq2db use following schema tables for ASE:

  • DataTypes
  • Procedures
  • ProcedureParameters

for other metadata we query system tables directly.

Why this feature is important for linq2db - schema provider used to generate data model from database using T4 templates.

Another important thing is support for CommandBehavior.SchemaOnly for procedures. Native provider (or in worst case ASE itself) has bug in this area, where it executes procedure for real which is very bad. See linq2db/linq2db#792. We fixed it for native provider on our side by wrapping such calls in transactions with rollback.

linq2db test: SchemaProviderTest.IncludeExcludeCatalogTest

Things to do before pushing out a new release

Items to do before pushing out a nuget package:

  • In .net core v1.0 and v1.1, calling AseConnection.Dispose() multiple times still causes an ObjectDisposedException. Looks to be because of the Close() call done by base.Dispose, but only in v1.0 and v1.1

    • It looks to be safe to remove the _disposed check, as Close also confirms the state isn't Closed already before continuing.
  • Write some tests comparing AseException and AseErrorCollection behaviour differences between reference and our driver

Different errors reported by native and managed providers when server is not available

native provider:

Result StackTrace:	
at Sybase.Data.AseClient1.AseConnection.Open()
   at Sybase.Data.AseClient.AseConnection.Open()
   at LinqToDB.Data.DataConnection.get_Connection() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 883
   at LinqToDB.Data.DataConnection.CreateCommand() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 979
   at LinqToDB.Data.DataConnection.get_Command() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 970
   at LinqToDB.DataProvider.DataProviderBase.InitCommand(DataConnection dataConnection, CommandType commandType, String commandText, DataParameter[] parameters) in c:\GitHub\linq2db.work\Source\LinqToDB\DataProvider\DataProviderBase.cs:line 104
   at LinqToDB.Data.DataConnection.InitCommand(CommandType commandType, String sql, DataParameter[] parameters, List`1 queryHints) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 950
   at LinqToDB.Data.CommandInfo.Execute[T]() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\CommandInfo.cs:line 549
   at LinqToDB.Data.DataConnectionExtensions.Execute[T](DataConnection connection, String sql) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnectionExtensions.cs:line 1069
   at Tests.DataProvider.SybaseTests.TestDate(String context) in c:\GitHub\linq2db.work\Tests\Linq\DataProvider\SybaseTests.cs:line 215
Result Message:	Sybase.Data.AseClient.AseException : There is no server listening at NOTHING_INTERESTING_HERE:5000.

AdoNetCore:

Result StackTrace:	
at AdoNetCore.AseClient.Internal.ConnectionPool.Reserve()
   at AdoNetCore.AseClient.Internal.ConnectionPoolManager.Reserve(String connectionString, IConnectionParameters parameters)
   at AdoNetCore.AseClient.AseConnection.Open()
   at LinqToDB.Data.DataConnection.get_Connection() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 883
   at LinqToDB.Data.DataConnection.CreateCommand() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 979
   at LinqToDB.Data.DataConnection.get_Command() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 970
   at LinqToDB.DataProvider.DataProviderBase.InitCommand(DataConnection dataConnection, CommandType commandType, String commandText, DataParameter[] parameters) in c:\GitHub\linq2db.work\Source\LinqToDB\DataProvider\DataProviderBase.cs:line 104
   at LinqToDB.Data.DataConnection.InitCommand(CommandType commandType, String sql, DataParameter[] parameters, List`1 queryHints) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnection.cs:line 950
   at LinqToDB.Data.CommandInfo.Execute[T]() in c:\GitHub\linq2db.work\Source\LinqToDB\Data\CommandInfo.cs:line 549
   at LinqToDB.Data.DataConnectionExtensions.Execute[T](DataConnection connection, String sql) in c:\GitHub\linq2db.work\Source\LinqToDB\Data\DataConnectionExtensions.cs:line 1069
   at Tests.DataProvider.SybaseTests.TestDate(String context) in c:\GitHub\linq2db.work\Tests\Linq\DataProvider\SybaseTests.cs:line 215
Result Message:	AdoNetCore.AseClient.AseException : Pool timed out trying to reserve a connection

I think message, given by native provider is much more informative and less misleading.

Decimal parameter type not inferred

When executing a stored procedure with a decimal parameter (e.g. 20000.00m), if the DbType is not specified, the driver sends the wrong details (type) to the server, resulting in

WARNING - Fatal Error 2780 occurred at {now()}. Please note the error and time, and contact a user with System Administrator (SA) authorization.

The workaround is to specify DbType.Decimal.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.