├── .gitignore
├── README.md
├── src
├── NReco.PrestoAdo
│ ├── PrestoDbParameter.cs
│ ├── PrestoDbFactory.cs
│ ├── NReco.PrestoAdo.csproj
│ ├── PrestoDbParameterCollection.cs
│ ├── PrestoConnectionStringBuilder.cs
│ ├── PrestoCommand.cs
│ ├── PrestoConnection.cs
│ └── PrestoDbDataReader.cs
└── NReco.PrestoAdo.sln
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs
2 | *.suo
3 | *[Bb]in/
4 | *[Oo]bj/
5 | *[Dd]ebug/
6 | *.user
7 | /src/packages
8 | *.lock.json
9 | *.nupkg
10 | *.dll
11 | *.targets
12 | project.lock.json
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NReco.PrestoAdo
2 | Presto/Trino ADO.NET Provider based on [PrestoClient](https://github.com/bamcis-io/PrestoClient).
3 |
4 | * uses Presto/Trino API v1 (headers prefix can be switched with "TrinoHeaders=1" in a connection string)
5 | * can connect to Metriql
6 | * compatible with .NET Core / NET6.
7 |
8 | Nuget package: [NReco.PrestoAdo](https://www.nuget.org/packages/NReco.PrestoAdo/)
9 |
10 | ## Connection string
11 |
12 | ```
13 | Host=hostName;Port=8080;UseSsl=false;Schema=defaultSchema;Catalog=catalog;User=user;Password=password;TrinoHeaders=1;
14 | ```
15 |
16 | ## Who is using this?
17 | NReco.PrestoAdo is in production use at [SeekTable.com](https://www.seektable.com/) and [PivotData microservice](https://www.nrecosite.com/pivotdata_service.aspx).
18 |
19 | ## License
20 | Copyright 2021-2022 Vitaliy Fedorchenko
21 |
22 | Distributed under the MIT license
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo/PrestoDbParameter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Common;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace NReco.PrestoAdo {
9 |
10 | public class PrestoDbParameter : DbParameter {
11 | public override DbType DbType { get; set; }
12 |
13 | public override ParameterDirection Direction { get => ParameterDirection.Input; set { } }
14 |
15 | public override bool IsNullable { get; set; }
16 |
17 | public override string ParameterName { get; set; }
18 |
19 | public override int Size { get; set; }
20 |
21 | public override string SourceColumn { get; set; }
22 |
23 | public override bool SourceColumnNullMapping { get; set; }
24 |
25 | public override object Value { get; set; }
26 |
27 | public override void ResetDbType() { }
28 |
29 | public override string ToString() => $"{ParameterName}:{Value}";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 NReco
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31702.278
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NReco.PrestoAdo", "NReco.PrestoAdo\NReco.PrestoAdo.csproj", "{8FD66739-5274-46F1-9E94-DC619F92D04E}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {8FD66739-5274-46F1-9E94-DC619F92D04E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {8FD66739-5274-46F1-9E94-DC619F92D04E}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {8FD66739-5274-46F1-9E94-DC619F92D04E}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {8FD66739-5274-46F1-9E94-DC619F92D04E}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {E89F9DF7-0F06-4B64-A155-30D620949959}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo/PrestoDbFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Data.Common;
6 |
7 | namespace NReco.PrestoAdo {
8 |
9 | public sealed class PrestoDbFactory : DbProviderFactory {
10 | public static readonly PrestoDbFactory Instance = new PrestoDbFactory();
11 |
12 | ///
13 | /// Returns a strongly typed instance.
14 | ///
15 | public override DbCommand CreateCommand() => new PrestoCommand();
16 |
17 | ///
18 | /// Returns a strongly typed instance.
19 | ///
20 | public override DbConnection CreateConnection() => new PrestoConnection();
21 |
22 | ///
23 | /// Returns a strongly typed instance.
24 | ///
25 | public override DbParameter CreateParameter() => new PrestoDbParameter();
26 |
27 | ///
28 | /// Returns a strongly typed instance.
29 | ///
30 | public override DbConnectionStringBuilder CreateConnectionStringBuilder() => new PrestoConnectionStringBuilder();
31 |
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo/NReco.PrestoAdo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ADO.NET Provider for Presto/Trino.
5 | Presto/Trino .NET driver
6 | Copyright (c) 2022 Vitalii Fedorchenko
7 | NReco.PrestoAdo
8 | 1.1.0
9 | Vitalii Fedorchenko
10 | netstandard2.0
11 | true
12 | NReco.PrestoAdo
13 | true
14 | NReco.PrestoAdo
15 | Presto;PrestoDB;Trino;ADO
16 | Source code: https://github.com/nreco/presto-ado
17 |
18 | v.1.1 changes:
19 | - updated PrestoClient reference to the newest 0.351.0-beta (can switch between Presto/Trino headers prefix)
20 | - added a connection string property TrinoHeaders (bool, false by default for the backward compatibility)
21 |
22 |
23 | https://www.nrecosite.com/img/nreco-logo-200.png
24 | https://github.com/nreco/presto-ado
25 | https://raw.githubusercontent.com/nreco/presto-ado/master/LICENSE
26 | https://github.com/nreco/presto-ado
27 | git
28 | false
29 | false
30 | false
31 | false
32 | false
33 | false
34 | false
35 | false
36 | false
37 | false
38 | NReco.PrestoAdo.snk
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo/PrestoDbParameterCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Data.Common;
4 | using System.Collections;
5 | using System.Threading.Tasks;
6 | using System.Linq;
7 |
8 | namespace NReco.PrestoAdo {
9 | internal class PrestoDbParameterCollection : DbParameterCollection {
10 | private readonly List parameters = new List();
11 |
12 | public override int Count => parameters.Count;
13 |
14 | public override object SyncRoot { get; }
15 |
16 | public override int Add(object value) {
17 | parameters.Add((PrestoDbParameter)value);
18 | return parameters.Count - 1;
19 | }
20 |
21 | public override void AddRange(Array values) => parameters.AddRange(values.Cast());
22 |
23 | public override void Clear() => parameters.Clear();
24 |
25 | public override bool Contains(object value) => parameters.Contains(value as PrestoDbParameter);
26 |
27 | public override bool Contains(string value) => parameters.Any(p => p.ParameterName == value);
28 |
29 | public override void CopyTo(Array array, int index) {
30 | for (int i = 0; i < parameters.Count; i++) {
31 | array.SetValue(parameters[i].Value, index + i);
32 | }
33 | }
34 |
35 | public override IEnumerator GetEnumerator() => parameters.GetEnumerator();
36 |
37 | public override int IndexOf(object value) => parameters.IndexOf(value as PrestoDbParameter);
38 |
39 | public override int IndexOf(string parameterName) => parameters.FindIndex(x => x.ParameterName == parameterName);
40 |
41 | public override void Insert(int index, object value) => parameters.Insert(index, (PrestoDbParameter)value);
42 |
43 | public override void Remove(object value) => parameters.Remove(value as PrestoDbParameter);
44 |
45 | public override void RemoveAt(int index) => parameters.RemoveAt(index);
46 |
47 | public override void RemoveAt(string parameterName) => parameters.RemoveAll(p => p.ParameterName == parameterName);
48 |
49 | protected override DbParameter GetParameter(int index) => parameters[index];
50 |
51 | protected override DbParameter GetParameter(string parameterName) => parameters[IndexOf(parameterName)];
52 |
53 | protected override void SetParameter(int index, DbParameter value) => parameters[index] = (PrestoDbParameter)value;
54 |
55 | protected override void SetParameter(string parameterName, DbParameter value) {
56 | var index = IndexOf(parameterName);
57 | if (index < 0)
58 | Add(value);
59 | else
60 | SetParameter(index, value);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo/PrestoConnectionStringBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Data.Common;
6 |
7 | namespace NReco.PrestoAdo {
8 | public class PrestoConnectionStringBuilder : DbConnectionStringBuilder {
9 | public PrestoConnectionStringBuilder() {
10 | }
11 |
12 | public PrestoConnectionStringBuilder(string connectionString) {
13 | ConnectionString = connectionString;
14 | }
15 |
16 | public string Host {
17 | get => TryGetValue("Host", out var value) ? value as string : "localhost";
18 | set => this["Host"] = value;
19 | }
20 |
21 | public ushort Port {
22 | get => TryGetValue("Port", out var value) && value is string @string && ushort.TryParse(@string, out var @ushort) ? @ushort : (ushort)8080;
23 | set => this["Port"] = value;
24 | }
25 |
26 | public bool TrinoHeaders {
27 | get => TryGetValue("TrinoHeaders", out var value) ? IsYesTrueOne(value) : false;
28 | set => this["TrinoHeaders"] = value;
29 | }
30 |
31 | public string User {
32 | get => TryGetValue("User", out var value) ? value as string : String.Empty;
33 | set => this["User"] = value;
34 | }
35 |
36 | public string Password {
37 | get => TryGetValue("Password", out var value) ? value as string : string.Empty;
38 | set => this["Password"] = value;
39 | }
40 |
41 | public string Catalog {
42 | get => TryGetValue("Catalog", out var value) ? value as string : null;
43 | set => this["Catalog"] = value;
44 | }
45 |
46 | public string Schema {
47 | get => TryGetValue("Schema", out var value) ? value as string : "default";
48 | set => this["Schema"] = value;
49 | }
50 |
51 | public int CheckInterval {
52 | get => TryGetValue("CheckInterval", out var value) && value is string @string && int.TryParse(@string, out var @int) ? @int : (int)800;
53 | set => this["CheckInterval"] = value;
54 | }
55 |
56 | public bool IgnoreSslErrors {
57 | get => TryGetValue("IgnoreSslErrors", out var value) ? IsYesTrueOne(value) : false;
58 | set => this["IgnoreSslErrors"] = value;
59 | }
60 |
61 | public bool UseSsl {
62 | get => TryGetValue("UseSsl", out var value) ? "true".Equals(value as string, StringComparison.OrdinalIgnoreCase) : false;
63 | set => this["UseSsl"] = value;
64 | }
65 |
66 | public int ClientRequestTimeout {
67 | get => TryGetValue("ClientRequestTimeout", out var value) && value is string @string && int.TryParse(@string, out var @int) ? @int : -1;
68 | set => this["ClientRequestTimeout"] = value;
69 | }
70 |
71 | bool IsYesTrueOne(object val) {
72 | var valStr = Convert.ToString(val);
73 | return valStr == "1"
74 | || "one".Equals(valStr, StringComparison.OrdinalIgnoreCase)
75 | || "true".Equals(valStr, StringComparison.OrdinalIgnoreCase);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/NReco.PrestoAdo/PrestoCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Data.Common;
6 | using System.Data;
7 | using System.Threading;
8 | using System.Text;
9 |
10 | namespace NReco.PrestoAdo {
11 | public class PrestoCommand : DbCommand {
12 |
13 | private readonly CancellationTokenSource cts = new CancellationTokenSource();
14 | private readonly PrestoDbParameterCollection commandParameters = new PrestoDbParameterCollection();
15 | private PrestoConnection connection;
16 |
17 | public PrestoCommand() {
18 | }
19 |
20 | public PrestoCommand(PrestoConnection connection) {
21 | this.connection = connection;
22 | }
23 |
24 | public override string CommandText { get; set; }
25 |
26 | public override int CommandTimeout { get; set; }
27 |
28 | public override CommandType CommandType { get; set; }
29 |
30 | public override bool DesignTimeVisible { get; set; }
31 |
32 | public override UpdateRowSource UpdatedRowSource { get; set; }
33 |
34 | protected override DbConnection DbConnection {
35 | get => connection;
36 | set => connection = (PrestoConnection)value;
37 | }
38 |
39 | protected override DbParameterCollection DbParameterCollection => commandParameters;
40 |
41 | protected override DbTransaction DbTransaction { get; set; }
42 |
43 | public new void Dispose() {
44 | cts?.Dispose();
45 | base.Dispose();
46 | }
47 |
48 | public override void Cancel() => cts.Cancel();
49 |
50 | public override int ExecuteNonQuery() => ExecuteNonQueryAsync(CancellationToken.None).GetAwaiter().GetResult();
51 |
52 | public override async Task ExecuteNonQueryAsync(CancellationToken cancellationToken) {
53 | if (connection == null)
54 | throw new InvalidOperationException("Connection is not set");
55 |
56 | using (var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken)) {
57 | var result = await connection.ExecuteQueryAsync(this, linkedCancellationTokenSource.Token).ConfigureAwait(false);
58 | }
59 | // ExecuteNonQuery may be used for INSERTs, let's return 1 affected record
60 | return 1;
61 | }
62 |
63 | public override object ExecuteScalar() => ExecuteScalarAsync(CancellationToken.None).GetAwaiter().GetResult();
64 |
65 | public override async Task