5
5
using System . Collections . Generic ;
6
6
using System . Diagnostics . CodeAnalysis ;
7
7
using System . Linq ;
8
+ using Octokit ;
8
9
using Xunit ;
9
10
10
11
namespace DuckDB . NET . Test ;
@@ -15,7 +16,7 @@ public class TableFunctionTests(DuckDBDatabaseFixture db) : DuckDBTestBase(db)
15
16
[ Fact ]
16
17
public void RegisterTableFunctionWithOneParameter ( )
17
18
{
18
- Connection . RegisterTableFunction < int > ( "demo" , ( parameters ) =>
19
+ Connection . RegisterTableFunction < int > ( "demo" , async ( parameters ) =>
19
20
{
20
21
var value = parameters [ 0 ] . GetValue < int > ( ) ;
21
22
@@ -33,119 +34,157 @@ public void RegisterTableFunctionWithOneParameter()
33
34
}
34
35
35
36
[ Fact ]
36
- public void RegisterTableFunctionWithTwoParameterTwoColumns ( )
37
+ public void RegisterTableFunctionWithTwoParameters ( )
37
38
{
38
- var count = 50 ;
39
-
40
- Connection . RegisterTableFunction < short , string > ( "demo2" , ( parameters ) =>
41
- {
42
- var start = parameters [ 0 ] . GetValue < short > ( ) ;
43
- var prefix = parameters [ 1 ] . GetValue < string > ( ) ;
44
-
45
- return new TableFunction ( new List < ColumnInfo > ( )
46
- {
47
- new ColumnInfo ( "foo" , typeof ( int ) ) ,
48
- new ColumnInfo ( "bar" , typeof ( string ) ) ,
49
- } , Enumerable . Range ( start , count ) . Select ( index => KeyValuePair . Create ( index , prefix + index ) ) ) ;
50
- } , ( item , writers , rowIndex ) =>
39
+ Connection . RegisterTableFunction < string , int > ( "github_search" , async ( parameters ) =>
51
40
{
52
- var pair = ( KeyValuePair < int , string > ) item ;
53
- writers [ 0 ] . WriteValue ( pair . Key , rowIndex ) ;
54
- writers [ 1 ] . WriteValue ( pair . Value , rowIndex ) ;
55
- } ) ;
56
-
57
- var data = Connection . Query < ( int , string ) > ( $ "SELECT * FROM demo2(30::SmallInt, 'DuckDB');") . ToList ( ) ;
58
-
59
- data . Select ( tuple => tuple . Item1 ) . Should ( ) . BeEquivalentTo ( Enumerable . Range ( 30 , count ) ) ;
60
- data . Select ( tuple => tuple . Item2 ) . Should ( ) . BeEquivalentTo ( Enumerable . Range ( 30 , count ) . Select ( i => $ "DuckDB{ i } ") ) ;
61
- }
41
+ var term = parameters [ 0 ] . GetValue < string > ( ) ;
42
+ var stars = parameters [ 1 ] . GetValue < int > ( ) ;
62
43
63
- [ Fact ]
64
- public void RegisterTableFunctionWithThreeParameters ( )
65
- {
66
- var count = 30 ;
67
- var startDate = new DateTime ( 2024 , 11 , 6 ) ;
68
- var minutesParam = 10 ;
69
- var secondsParam = 2.5 ;
70
-
71
- Connection . RegisterTableFunction < DateTime , long , double > ( "demo3" , ( parameters ) =>
72
- {
73
- var date = parameters [ 0 ] . GetValue < DateTime > ( ) ;
74
- var minutes = parameters [ 1 ] . GetValue < long > ( ) ;
75
- var seconds = parameters [ 2 ] . GetValue < double > ( ) ;
44
+ var client = new GitHubClient ( new ProductHeaderValue ( "DuckDB-Table-Valued-Function" ) ) ;
76
45
77
- return new TableFunction ( new List < ColumnInfo > ( )
46
+ var request = new SearchRepositoriesRequest ( term )
78
47
{
79
- new ColumnInfo ( "foo" , typeof ( DateTime ) ) ,
80
- } , Enumerable . Range ( 0 , count ) . Select ( i => date . AddDays ( i ) . AddMinutes ( minutes ) . AddSeconds ( seconds ) ) ) ;
81
- } , ( item , writers , rowIndex ) =>
82
- {
83
- writers [ 0 ] . WriteValue ( ( DateTime ) item , rowIndex ) ;
84
- } ) ;
85
-
86
- var data = Connection . Query < DateTime > ( $ "SELECT * FROM demo3('2024-11-06'::TIMESTAMP, 10, 2.5 );") . ToList ( ) ;
48
+ Stars = new Octokit . Range ( stars , SearchQualifierOperator . GreaterThan )
49
+ } ;
87
50
88
- var dateTimes = Enumerable . Range ( 0 , count ) . Select ( i => startDate . AddDays ( i ) . AddMinutes ( minutesParam ) . AddSeconds ( secondsParam ) ) ;
89
- data . Should ( ) . BeEquivalentTo ( dateTimes ) ;
90
- }
51
+ var result = await client . Search . SearchRepo ( request ) ;
91
52
92
- [ Fact ]
93
- public void RegisterTableFunctionWithFourParameters ( )
94
- {
95
- var guid = Guid . NewGuid ( ) ;
96
-
97
- Connection . RegisterTableFunction < bool , decimal , byte , Guid > ( "demo4" , ( parameters ) =>
98
- {
99
- var param1 = parameters [ 0 ] . GetValue < bool > ( ) ;
100
- var param2 = parameters [ 1 ] . GetValue < decimal > ( ) ;
101
- var param3 = parameters [ 2 ] . GetValue < byte > ( ) ;
102
- var param4 = parameters [ 3 ] . GetValue < Guid > ( ) ;
103
-
104
- var enumerable = param4 . ToByteArray ( param1 ) . Append ( param3 ) ;
105
-
106
53
return new TableFunction ( new List < ColumnInfo > ( )
107
54
{
108
- new ColumnInfo ( "foo" , typeof ( byte ) ) ,
109
- } , enumerable ) ;
55
+ new ColumnInfo ( "name" , typeof ( string ) ) ,
56
+ new ColumnInfo ( "description" , typeof ( string ) ) ,
57
+ new ColumnInfo ( "stargazers" , typeof ( int ) ) ,
58
+ new ColumnInfo ( "url" , typeof ( string ) ) ,
59
+ new ColumnInfo ( "owner" , typeof ( string ) ) ,
60
+ } , result . Items ) ;
110
61
} , ( item , writers , rowIndex ) =>
111
62
{
112
- writers [ 0 ] . WriteValue ( ( byte ) item , rowIndex ) ;
63
+ var repo = ( Repository ) item ;
64
+ writers [ 0 ] . WriteValue ( repo . Name , rowIndex ) ;
65
+ writers [ 1 ] . WriteValue ( repo . Description , rowIndex ) ;
66
+ writers [ 2 ] . WriteValue ( repo . StargazersCount , rowIndex ) ;
67
+ writers [ 3 ] . WriteValue ( repo . Url , rowIndex ) ;
68
+ writers [ 4 ] . WriteValue ( repo . Owner . Login , rowIndex ) ;
113
69
} ) ;
114
70
115
- var data = Connection . Query < byte > ( $ "SELECT * FROM demo4(false, 10::DECIMAL(18, 3), 4::UTINYINT, '{ guid } '::UUID );") . ToList ( ) ;
116
-
117
- var bytes = guid . ToByteArray ( false ) . Append ( ( byte ) 4 ) ;
118
- data . Should ( ) . BeEquivalentTo ( bytes ) ;
71
+ var data = Connection . Query < ( string , string , int , string , string ) > ( "SELECT * FROM github_search('duckdb', 400);" ) . ToList ( ) ;
119
72
}
120
73
121
- [ Fact ]
122
- public void RegisterTableFunctionWithEmptyResult ( )
123
- {
124
- Connection . RegisterTableFunction < sbyte , ushort , uint , ulong , float > ( "demo5" , ( parameters ) =>
125
- {
126
- var param1 = parameters [ 0 ] . GetValue < sbyte > ( ) ;
127
- var param2 = parameters [ 1 ] . GetValue < ushort > ( ) ;
128
- var param3 = parameters [ 2 ] . GetValue < uint > ( ) ;
129
- var param4 = parameters [ 3 ] . GetValue < ulong > ( ) ;
130
- var param5 = parameters [ 4 ] . GetValue < float > ( ) ;
131
-
132
- param1 . Should ( ) . Be ( 1 ) ;
133
- param2 . Should ( ) . Be ( 2 ) ;
134
- param3 . Should ( ) . Be ( 3 ) ;
135
- param4 . Should ( ) . Be ( 4 ) ;
136
- param5 . Should ( ) . Be ( 5.6f ) ;
137
-
138
- return new TableFunction ( new List < ColumnInfo > ( )
139
- {
140
- new ColumnInfo ( "foo" , typeof ( int ) ) ,
141
- } , Enumerable . Empty < int > ( ) ) ;
142
- } , ( item , writers , rowIndex ) =>
143
- {
144
- writers [ 0 ] . WriteValue ( ( int ) item , rowIndex ) ;
145
- } ) ;
146
-
147
- var data = Connection . Query < int > ( $ "SELECT * FROM demo5(1::TINYINT, 2::USMALLINT, 3::UINTEGER, 4::UBIGINT, 5.6);") . ToList ( ) ;
148
-
149
- data . Should ( ) . BeEquivalentTo ( Enumerable . Empty < int > ( ) ) ;
150
- }
74
+ //[Fact]
75
+ //public void RegisterTableFunctionWithTwoParameterTwoColumns()
76
+ //{
77
+ // var count = 50;
78
+
79
+ // Connection.RegisterTableFunction<short, string>("demo2", (parameters) =>
80
+ // {
81
+ // var start = parameters[0].GetValue<short>();
82
+ // var prefix = parameters[1].GetValue<string>();
83
+
84
+ // return new TableFunction(new List<ColumnInfo>()
85
+ // {
86
+ // new ColumnInfo("foo", typeof(int)),
87
+ // new ColumnInfo("bar", typeof(string)),
88
+ // }, Enumerable.Range(start, count).Select(index => KeyValuePair.Create(index, prefix + index)));
89
+ // }, (item, writers, rowIndex) =>
90
+ // {
91
+ // var pair = (KeyValuePair<int, string>)item;
92
+ // writers[0].WriteValue(pair.Key, rowIndex);
93
+ // writers[1].WriteValue(pair.Value, rowIndex);
94
+ // });
95
+
96
+ // var data = Connection.Query<(int, string)>($"SELECT * FROM demo2(30::SmallInt, 'DuckDB');").ToList();
97
+
98
+ // data.Select(tuple => tuple.Item1).Should().BeEquivalentTo(Enumerable.Range(30, count));
99
+ // data.Select(tuple => tuple.Item2).Should().BeEquivalentTo(Enumerable.Range(30, count).Select(i => $"DuckDB{i}"));
100
+ //}
101
+
102
+ //[Fact]
103
+ //public void RegisterTableFunctionWithThreeParameters()
104
+ //{
105
+ // var count = 30;
106
+ // var startDate = new DateTime(2024, 11, 6);
107
+ // var minutesParam = 10;
108
+ // var secondsParam = 2.5;
109
+
110
+ // Connection.RegisterTableFunction<DateTime, long, double>("demo3", (parameters) =>
111
+ // {
112
+ // var date = parameters[0].GetValue<DateTime>();
113
+ // var minutes = parameters[1].GetValue<long>();
114
+ // var seconds = parameters[2].GetValue<double>();
115
+
116
+ // return new TableFunction(new List<ColumnInfo>()
117
+ // {
118
+ // new ColumnInfo("foo", typeof(DateTime)),
119
+ // }, Enumerable.Range(0, count).Select(i => date.AddDays(i).AddMinutes(minutes).AddSeconds(seconds)));
120
+ // }, (item, writers, rowIndex) =>
121
+ // {
122
+ // writers[0].WriteValue((DateTime)item, rowIndex);
123
+ // });
124
+
125
+ // var data = Connection.Query<DateTime>($"SELECT * FROM demo3('2024-11-06'::TIMESTAMP, 10, 2.5 );").ToList();
126
+
127
+ // var dateTimes = Enumerable.Range(0, count).Select(i => startDate.AddDays(i).AddMinutes(minutesParam).AddSeconds(secondsParam));
128
+ // data.Should().BeEquivalentTo(dateTimes);
129
+ //}
130
+
131
+ //[Fact]
132
+ //public void RegisterTableFunctionWithFourParameters()
133
+ //{
134
+ // var guid = Guid.NewGuid();
135
+
136
+ // Connection.RegisterTableFunction<bool, decimal, byte, Guid>("demo4", (parameters) =>
137
+ // {
138
+ // var param1 = parameters[0].GetValue<bool>();
139
+ // var param2 = parameters[1].GetValue<decimal>();
140
+ // var param3 = parameters[2].GetValue<byte>();
141
+ // var param4 = parameters[3].GetValue<Guid>();
142
+
143
+ // var enumerable = param4.ToByteArray(param1).Append(param3);
144
+
145
+ // return new TableFunction(new List<ColumnInfo>()
146
+ // {
147
+ // new ColumnInfo("foo", typeof(byte)),
148
+ // }, enumerable);
149
+ // }, (item, writers, rowIndex) =>
150
+ // {
151
+ // writers[0].WriteValue((byte)item, rowIndex);
152
+ // });
153
+
154
+ // var data = Connection.Query<byte>($"SELECT * FROM demo4(false, 10::DECIMAL(18, 3), 4::UTINYINT, '{guid}'::UUID );").ToList();
155
+
156
+ // var bytes = guid.ToByteArray(false).Append((byte)4);
157
+ // data.Should().BeEquivalentTo(bytes);
158
+ //}
159
+
160
+ //[Fact]
161
+ //public void RegisterTableFunctionWithEmptyResult()
162
+ //{
163
+ // Connection.RegisterTableFunction<sbyte, ushort, uint, ulong, float>("demo5", (parameters) =>
164
+ // {
165
+ // var param1 = parameters[0].GetValue<sbyte>();
166
+ // var param2 = parameters[1].GetValue<ushort>();
167
+ // var param3 = parameters[2].GetValue<uint>();
168
+ // var param4 = parameters[3].GetValue<ulong>();
169
+ // var param5 = parameters[4].GetValue<float>();
170
+
171
+ // param1.Should().Be(1);
172
+ // param2.Should().Be(2);
173
+ // param3.Should().Be(3);
174
+ // param4.Should().Be(4);
175
+ // param5.Should().Be(5.6f);
176
+
177
+ // return new TableFunction(new List<ColumnInfo>()
178
+ // {
179
+ // new ColumnInfo("foo", typeof(int)),
180
+ // }, Enumerable.Empty<int>());
181
+ // }, (item, writers, rowIndex) =>
182
+ // {
183
+ // writers[0].WriteValue((int)item, rowIndex);
184
+ // });
185
+
186
+ // var data = Connection.Query<int>($"SELECT * FROM demo5(1::TINYINT, 2::USMALLINT, 3::UINTEGER, 4::UBIGINT, 5.6);").ToList();
187
+
188
+ // data.Should().BeEquivalentTo(Enumerable.Empty<int>());
189
+ //}
151
190
}
0 commit comments