Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First round of converting System.Data.OleDb to COMWrappers #54822

Merged
merged 38 commits into from
Sep 21, 2021

Conversation

kant2002
Copy link
Contributor

This change just remove warning from ILLink and do not make attempt
to convert other COM object creation to use ComWrappers

Also I have to add target net5.0-windows where ComWrappers would be
used. Same concerns regarding testing as in
#54636

Two calls inside OleDbDataAdapter call GetErrorInfo but do not do anything with results. That's probably mistake from previous refactoring. These parts does not touched and left as is. Need advice on that specific parts how to proceed.

This change just remove warning from ILLink and do not make attempt
to convert other COM object creation to use ComWrappers

Also I have to add target net5.0-windows where ComWrappers would be
used. Same concerns regarding testing as in
dotnet#54636

Two calls inside OleDbDataAdapter call GetErrorInfo but do not do anything with results. That's probably mistake from previous refactoring. These parts does not touched and left as is. Need advice on that specific parts how to proceed.
@ghost
Copy link

ghost commented Jun 28, 2021

Tagging subscribers to this area: @roji, @ajcvickers
See info in area-owners.md if you want to be subscribed.

Issue Details

This change just remove warning from ILLink and do not make attempt
to convert other COM object creation to use ComWrappers

Also I have to add target net5.0-windows where ComWrappers would be
used. Same concerns regarding testing as in
#54636

Two calls inside OleDbDataAdapter call GetErrorInfo but do not do anything with results. That's probably mistake from previous refactoring. These parts does not touched and left as is. Need advice on that specific parts how to proceed.

Author: kant2002
Assignees: -
Labels:

area-System.Data

Milestone: -

@jkotas
Copy link
Member

jkotas commented Jun 28, 2021

cc @AaronRobinsonMSFT @eerhardt

[DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)]
internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo(
[In] int dwReserved,
[Out] out System.IntPtr ppIErrorInfo);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use out in P/Invokes, but instead use pointers. This matches the native signatures as close as possible, and allows for the native marshalling to do less work. In this case, the native marshalling needs to pin the managed reference out IntPtr ppIErrorInfo. But it doesn't if the signature is a pointer.

Suggested change
[Out] out System.IntPtr ppIErrorInfo);
[Out] System.IntPtr* ppIErrorInfo);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also drop the [Out] attribute.

kant2002 and others added 4 commits June 30, 2021 19:45
<Compile Include="OleDbConnection.COMWrappers.cs" />
<Compile Include="OleDbException.COMWrappers.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETStandard'">
Copy link
Member

@eerhardt eerhardt Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right? Don't you want the ! of the above condition on line 102?

Or maybe even just not on TargetFramework net5.0 compatible, but still on Windows:

  <ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net5.0')) and '$(TargetsWindows)' == 'true'">

Copy link
Member

@ViktorHofer ViktorHofer Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would include net461-windows which is wrong as that's facade assembly. The condition is probably missing a '$(TargetsWindows)' == 'true'.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I would use

<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net5.0')) and'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetsWindows)' == 'true'">

to be symmetrical with the first ItemGroup condition above.

<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetsWindows)' == 'true'">

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ViktorHofer and @eerhardt I made changes, but I'm not sure if this is proper way. All I can say, not it does not fails during build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good. My only comments would be to make the ItemGroup conditions in the same order, to help with readability:

  <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetsWindows)' == 'true'">
...
  <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', $(NetCoreAppCurrent))) and '$(TargetsWindows)' == 'true'">
...
  <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and !$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', $(NetCoreAppCurrent))) and '$(TargetsWindows)' == 'true'">

would become

  <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetsWindows)' == 'true'">
...
  <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetsWindows)' == 'true' and $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', $(NetCoreAppCurrent)))">
...
  <ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetsWindows)' == 'true' and !$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', $(NetCoreAppCurrent)))">

And then change the IsTargetFrameworkCompatible to use net5.0, since COMWrappers were introduced in net5.0. This helps with maintainability in the long term, when we update NetCoreAppCurrent to be net7.0 in the future.

{
internal static partial class ODB
{
internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code here between COMWrappers and NoCOMWrappers looks duplicated. Can it be folded back together?


public sealed partial class OleDbConnection
{
internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we share the bulk of this code, and only pull out the differences into COMWrappers vs. NoCOMWrappers files? i.e. create new private methods on the partial classes.

@@ -11,7 +11,7 @@

namespace System.Data.OleDb
{
public sealed class OleDbException : System.Data.Common.DbException
public sealed partial class OleDbException : System.Data.Common.DbException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be partial? I don't see the other side of the partial class.

@@ -70,13 +70,8 @@ internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo er
string? message = null;
string? source = null;
OleDbHResult hr = 0;

if (null != errorInfo)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we need a null check here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There discussion about that #54822 (comment)


namespace System.Data.OleDb
{
using SysTx = Transactions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this using used?

@kant2002
Copy link
Contributor Author

@eerhardt can you take a look? Also do I need to pursue creation of fake OleDbProvider to test for error condition which you notice?

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking really good. I just had a few final comments. After these are addressed, I won't have anymore concerns. Would also be good to get @AaronRobinsonMSFT to sign off.

src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Outdated Show resolved Hide resolved
src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Outdated Show resolved Hide resolved
return e;
}

internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a difference in the code of OnInfoMessage between the COMWrappers file and the NoCOMWrappers file. Why do we need them split?

OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo
if ((OleDbHResult.S_OK == hr) && (IntPtr.Zero != pErrorInfo))
{
UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just split this line out into separate partial methods between the two? That way we don't need to duplicate this whole method?

src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs Outdated Show resolved Hide resolved
src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs Outdated Show resolved Hide resolved
Comment on lines 16 to 17
[In] int dwReserved,
[Out, MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[In] int dwReserved,
[Out, MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo);
int dwReserved,
[MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo);

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. Thanks for the contribution here, @kant2002! I like how this change cleaned up, and really didn't need that much changes in the end.

@kant2002
Copy link
Contributor Author

Yeah, @eerhardt your proposal to consolidate files was excellent. I remove 4 not needed files and that was great.

@eerhardt
Copy link
Member

@lewing @radical - is this a known issue? I can't see how this change could have caused this failure in the browser wasm staging leg.

src\mono\mono.proj(492,5): error MSB3073: (NETCORE_ENGINEERING_TELEMETRY=Build) The command "call "D:\workspace\_work\1\s\eng\native\init-vs-env.cmd" && call "D:\workspace\_work\1\s\src\mono\wasm\emsdk\emsdk_env.bat" && emcmake cmake -DENABLE_WERROR=1 -G Ninja -DCMAKE_INSTALL_PREFIX="D:\workspace\_work\1\s\artifacts\obj\mono\Browser.wasm.Release\out" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DGC_SUSPEND=preemptive -DMONO_LIB_NAME=monosgen-2.0 -DMONO_SHARED_LIB_NAME=monosgen-2.0 -DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,shared_perfcounters,interpreter,threads,qcalls,debugger_agent,log_dest,assert_messages -DENABLE_INTERP_LIB=1 -DDISABLE_ICALL_TABLES=1 -DENABLE_ICALL_EXPORT=1 -DENABLE_LAZY_GC_THREAD_CREATION=1 -DENABLE_LLVM_RUNTIME=1 -DSTATIC_COMPONENTS=1 -DMONO_COMPONENTS_RID=Browser-wasm -DCMAKE_C_FLAGS=" -fexceptions \"-ID:\workspace\_work\1\s\.packages\microsoft.netcore.runtime.icu.transport\7.0.0-alpha.1.21463.1\runtimes\browser-wasm\native\include\"" -DCMAKE_CXX_FLAGS=" -fexceptions" "D:\workspace\_work\1\s\src\mono"" exited with code 9009

@radical
Copy link
Member

radical commented Sep 21, 2021

This failed because emsdk could not be activated:

  HEAD is now at f44b841 2.0.23 (#828)
  Error: Downloading URL 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v14.15.5-win-x64.zip': <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>
  Warning: Possibly SSL/TLS issue. Update or install Python SSL root certificates (2048-bit or greater) supplied in Python folder or https://pypi.org/project/certifi/ and try again.
  Installation failed!

@radekdoulik the update machine certs step passed. Is this a network issue?

@eerhardt
Copy link
Member

It must have been a network issue. I ran it for the 3rd time, and it looks like it is further than it was before.

I'll merge this once that leg goes green.

@eerhardt eerhardt merged commit 3de6468 into dotnet:main Sep 21, 2021
@kant2002 kant2002 deleted the kant/remove-il2050-oledb branch September 22, 2021 10:32
@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Data community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants