Fix data and test infrastructure and scaffolding (#82)

* Fix local references.

* Optimize, fix and simplify JetDataReader.

* Only scaffold objects if tables are available.

* Fix test infrastructure.

* Ignore Development.props in root folder.
pull/84/head
Laurents Meyer 5 years ago committed by GitHub
parent 23b8257fc8
commit f094f3658c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

2
.gitignore vendored

@ -165,4 +165,4 @@ $RECYCLE.BIN/
/msbuild/Output
/.vs/EntityFrameworkCore.Jet
.idea
!/build/
Development.props

@ -1,26 +0,0 @@
<Project>
<PropertyGroup>
<!--
Specify the absolute path to the EntityFrameworkCore base directory,
to compile against that version for better development and local
debugging support.
Rename this file "development.props".
The EFCore assemblies are being compiled with an AssemblyVersion of
"42.42.42.42" by default. To not get any compilation errors
for the EFCore.MySql.IntegrationTests project, which uses
Microsoft.AspNetCore.Identity.EntityFrameworkCore, which references
it's own version of EFCore, you have to make sure, that your local
EFCore assemblies are compiled with an AssemblyVersion <= the one
referenced by Microsoft.AspNetCore.Identity.EntityFrameworkCore
(e.g. "3.1.0.0").
To achive that, run the following command in your EntityFrameworkCore
base directory:
dotnet build "/p:AssemblyVersion=3.1.0.0"
-->
<LocalEFCoreRepository>E:\Sources\EntityFrameworkCore-3.1</LocalEFCoreRepository>
</PropertyGroup>
</Project>

@ -1,6 +1,6 @@
<Project>
<Import Project="Version.props" />
<Import Project=".\build\Development.props" Condition="Exists('.\build\Development.props')" />
<Import Project="Development.props" Condition="Exists('Development.props')" />
<PropertyGroup>
<Product>EntityFrameworkCore.Jet</Product>

@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Text;
using System.Threading;
@ -49,13 +50,15 @@ namespace EntityFrameworkCore.Jet.Data
public override bool GetBoolean(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError)
if (JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value))
{
if (value is DBNull) return false;
return default;
}
if (value is bool boolValue)
return boolValue;
if (value is sbyte sbyteValue)
return sbyteValue != 0;
if (value is byte byteValue)
@ -80,14 +83,16 @@ namespace EntityFrameworkCore.Jet.Data
public override byte GetByte(int ordinal)
{
var value = GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError)
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value))
{
if (value is DBNull) return 0;
return default;
}
if (value is byte byteValue)
return byteValue;
if (value is sbyte sbyteValue)
return checked((byte) sbyteValue);
if (value is short shortValue)
@ -104,36 +109,33 @@ namespace EntityFrameworkCore.Jet.Data
return checked((byte) ulongValue);
if (value is decimal decimalValue)
return (byte) decimalValue;
return (byte) value;
}
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
return _wrappedDataReader.GetBytes(ordinal, dataOffset, buffer, bufferOffset, length);
}
=> JetConfiguration.UseDefaultValueOnDBNullConversionError &&
_wrappedDataReader.IsDBNull(ordinal)
? 0
: _wrappedDataReader.GetBytes(ordinal, dataOffset, buffer, bufferOffset, length);
public override char GetChar(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return (char)0;
}
return (char) value;
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: (char) value;
}
public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
if (JetConfiguration.UseDefaultValueOnDBNullConversionError &&
_wrappedDataReader.IsDBNull(ordinal))
{
return 0;
}
return _wrappedDataReader.GetChars(ordinal, dataOffset, buffer, bufferOffset, length);
}
@ -143,11 +145,10 @@ namespace EntityFrameworkCore.Jet.Data
public override DateTime GetDateTime(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified);
}
return _wrappedDataReader.GetDateTime(ordinal);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: (DateTime) value;
}
public virtual TimeSpan GetTimeSpan(int ordinal)
@ -159,21 +160,19 @@ namespace EntityFrameworkCore.Jet.Data
public override decimal GetDecimal(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
return Convert.ToDecimal(value);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: Convert.ToDecimal(value);
}
public override double GetDouble(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
return Convert.ToDouble(value);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: Convert.ToDouble(value);
}
public override System.Collections.IEnumerator GetEnumerator()
@ -185,63 +184,52 @@ namespace EntityFrameworkCore.Jet.Data
public override float GetFloat(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
return Convert.ToSingle(value);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: Convert.ToSingle(value);
}
public override Guid GetGuid(int ordinal)
{
// Fix for discussion https://jetentityframeworkprovider.codeplex.com/discussions/647028
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return Guid.Empty;
}
if (value is byte[])
return new Guid((byte[]) value);
else
return _wrappedDataReader.GetGuid(ordinal);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? Guid.Empty
: value is byte[] bytes
? new Guid(bytes)
: (Guid)value;
}
public override short GetInt16(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
return Convert.ToInt16(value);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: Convert.ToInt16(value);
}
public override int GetInt32(int ordinal)
{
// Fix for discussion https://jetentityframeworkprovider.codeplex.com/discussions/647028
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
else if (value is string)
{
var buffer = Encoding.Unicode.GetBytes((string)value);
var intValue = BitConverter.ToInt32(buffer, 0);
return intValue;
}
else
return Convert.ToInt32(value);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: value is string stringValue
? BitConverter.ToInt32(Encoding.Unicode.GetBytes(stringValue), 0)
: Convert.ToInt32(value);
}
public override long GetInt64(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return 0;
}
return Convert.ToInt64(value);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? default
: Convert.ToInt64(value);
}
public override string GetName(int ordinal)
@ -249,35 +237,76 @@ namespace EntityFrameworkCore.Jet.Data
public override int GetOrdinal(string name)
=> _wrappedDataReader.GetOrdinal(name);
public override DataTable GetSchemaTable()
=> _wrappedDataReader.GetSchemaTable();
public override string GetString(int ordinal)
{
var value = _wrappedDataReader.GetValue(ordinal);
if (JetConfiguration.UseDefaultValueOnDBNullConversionError && value is DBNull)
{
return "";
}
return _wrappedDataReader.GetString(ordinal);
return JetConfiguration.UseDefaultValueOnDBNullConversionError &&
Convert.IsDBNull(value)
? string.Empty
: (string) value;
}
public override object GetValue(int ordinal)
=> _wrappedDataReader.GetValue(ordinal);
public override T GetFieldValue<T>(int ordinal)
{
if (typeof(T) == typeof(TimeSpan))
return (T) (object) GetTimeSpan(ordinal);
else if (typeof(T) == typeof(DateTimeOffset))
return (T) (object) GetDateTimeOffset(ordinal);
else
return base.GetFieldValue<T>(ordinal);
var fieldType = GetFieldType(ordinal);
if (fieldType == typeof(bool))
return GetBoolean(ordinal);
if (fieldType == typeof(byte))
return GetByte(ordinal);
// if (fieldType == typeof(sbyte))
// return GetSByte(ordinal);
if (fieldType == typeof(short))
return GetInt16(ordinal);
// if (fieldType == typeof(ushort))
// return GetUInt16(ordinal);
if (fieldType == typeof(int))
return GetInt32(ordinal);
// if (fieldType == typeof(uint))
// return GetUInt32(ordinal);
if (fieldType == typeof(long))
return GetInt64(ordinal);
// if (fieldType == typeof(ulong))
// return GetUInt64(ordinal);
if (fieldType == typeof(char))
return GetChar(ordinal);
if (fieldType == typeof(decimal))
return GetDecimal(ordinal);
if (fieldType == typeof(double))
return GetDouble(ordinal);
if (fieldType == typeof(float))
return GetFloat(ordinal);
if (fieldType == typeof(string))
return GetString(ordinal);
if (fieldType == typeof(DateTime))
return GetDateTime(ordinal);
if (fieldType == typeof(DateTimeOffset))
return GetDateTimeOffset(ordinal);
if (fieldType == typeof(Guid))
return GetGuid(ordinal);
if (fieldType == typeof(Stream))
return GetStream(ordinal);
if (fieldType == typeof(TextReader) || fieldType == typeof(StringReader))
return GetTextReader(ordinal);
if (fieldType == typeof(TimeSpan))
return GetTimeSpan(ordinal);
return _wrappedDataReader.GetValue(ordinal);
}
public override int GetValues(object[] values)
=> _wrappedDataReader.GetValues(values);
{
var count = Math.Min((values ?? throw new ArgumentNullException(nameof(values))).Length, FieldCount);
for (var i = 0; i < count; i++)
values[i] = GetValue(i);
return count;
}
public override bool HasRows
=> _wrappedDataReader.HasRows;
@ -286,13 +315,8 @@ namespace EntityFrameworkCore.Jet.Data
=> _wrappedDataReader.IsClosed;
public override bool IsDBNull(int ordinal)
{
if (_wrappedDataReader.IsDBNull(ordinal))
return true;
if (JetConfiguration.IntegerNullValue != null && ((int) JetConfiguration.IntegerNullValue).Equals(_wrappedDataReader.GetValue(ordinal)))
return true;
return false;
}
=> _wrappedDataReader.IsDBNull(ordinal) ||
JetConfiguration.IntegerNullValue != null && ((int) JetConfiguration.IntegerNullValue).Equals(GetValue(ordinal));
public override bool NextResult()
=> _wrappedDataReader.NextResult();

@ -20,4 +20,13 @@
<PackageReference Include="System.Data.Odbc" />
</ItemGroup>
<ItemGroup Condition="'$(LocalEFCoreRepository)' != ''">
<Reference Include="Microsoft.EntityFrameworkCore">
<HintPath>$(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(DefaultNetStandardTargetFramework)\Microsoft.EntityFrameworkCore.dll</HintPath>
</Reference>
<Reference Include="Microsoft.EntityFrameworkCore.Abstractions">
<HintPath>$(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(DefaultNetStandardTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

@ -20,4 +20,13 @@
<PackageReference Include="System.Data.OleDb" />
</ItemGroup>
<ItemGroup Condition="'$(LocalEFCoreRepository)' != ''">
<Reference Include="Microsoft.EntityFrameworkCore">
<HintPath>$(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(DefaultNetStandardTargetFramework)\Microsoft.EntityFrameworkCore.dll</HintPath>
</Reference>
<Reference Include="Microsoft.EntityFrameworkCore.Abstractions">
<HintPath>$(LocalEFCoreRepository)\artifacts\bin\EFCore.Relational\Debug\$(DefaultNetStandardTargetFramework)\Microsoft.EntityFrameworkCore.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

@ -164,10 +164,13 @@ namespace EntityFrameworkCore.Jet.Scaffolding.Internal
}
}
}
GetColumns(connection, tables);
GetIndexes(connection, tables);
GetRelations(connection, tables);
if (tables.Count > 0)
{
GetColumns(connection, tables);
GetIndexes(connection, tables);
GetRelations(connection, tables);
}
return tables;
}

@ -2,11 +2,8 @@
using System.Diagnostics;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
using EntityFrameworkCore.Jet.Diagnostics.Internal;
using EntityFrameworkCore.Jet.Metadata.Internal;
using EntityFrameworkCore.Jet.Scaffolding.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.TestUtilities;
@ -23,62 +20,5 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities
new LoggingOptions(),
new DiagnosticListener("Fake"),
new JetLoggingDefinitions()));
protected override bool AcceptTable(DatabaseTable table) => !(table is DatabaseView);
protected override bool AcceptIndex(DatabaseIndex index)
=> false;
private readonly string _dropViewsSql = @"
DECLARE @name VARCHAR(MAX) = '__dummy__', @SQL VARCHAR(MAX) = '';
WHILE @name IS NOT NULL
BEGIN
SELECT @name =
(SELECT TOP 1 QUOTENAME(s.`name`) + '.' + QUOTENAME(o.`name`)
FROM sysobjects o
INNER JOIN sys.views v ON o.id = v.object_id
INNER JOIN sys.schemas s ON s.schema_id = v.schema_id
WHERE (s.name = 'dbo' OR s.principal_id <> s.schema_id) AND o.`type` = 'V' AND o.category = 0 AND o.`name` NOT IN
(
SELECT referenced_entity_name
FROM sys.sql_expression_dependencies AS sed
INNER JOIN sys.objects AS o ON sed.referencing_id = o.object_id
)
ORDER BY v.`name`)
SELECT @SQL = 'DROP VIEW ' + @name
EXEC (@SQL)
END";
protected override string BuildCustomSql(DatabaseModel databaseModel)
=> _dropViewsSql;
protected override string BuildCustomEndingSql(DatabaseModel databaseModel)
=> _dropViewsSql
+ @"
GO
DECLARE @SQL VARCHAR(MAX) = '';
SELECT @SQL = @SQL + 'DROP FUNCTION ' + QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME) + ';'
FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE ROUTINE_TYPE = 'FUNCTION' AND ROUTINE_BODY = 'SQL';
EXEC (@SQL);
SET @SQL ='';
SELECT @SQL = @SQL + 'DROP AGGREGATE ' + QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME) + ';'
FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE ROUTINE_TYPE = 'FUNCTION' AND ROUTINE_BODY = 'EXTERNAL';
EXEC (@SQL);
SET @SQL ='';
SELECT @SQL = @SQL + 'DROP PROC ' + QUOTENAME(schema_name(schema_id)) + '.' + QUOTENAME(name) + ';' FROM sys.procedures;
EXEC (@SQL);
SET @SQL ='';
SELECT @SQL = @SQL + 'DROP TYPE ' + QUOTENAME(schema_name(schema_id)) + '.' + QUOTENAME(name) + ';' FROM sys.types WHERE is_user_defined = 1;
EXEC (@SQL);
SET @SQL ='';
SELECT @SQL = @SQL + 'DROP SCHEMA ' + QUOTENAME(name) + ';' FROM sys.schemas WHERE principal_id <> schema_id;
EXEC (@SQL);";
}
}

@ -18,6 +18,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit.core" />
<PackageReference Include="xunit.assert" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="xunit.runner.console" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" />
<PackageReference Include="Moq" />

Loading…
Cancel
Save