55using System . Collections . Generic ;
66using System . Diagnostics . CodeAnalysis ;
77using System . Linq ;
8+ using Octokit ;
89using Xunit ;
910
1011namespace DuckDB . NET . Test ;
@@ -15,7 +16,7 @@ public class TableFunctionTests(DuckDBDatabaseFixture db) : DuckDBTestBase(db)
1516 [ Fact ]
1617 public void RegisterTableFunctionWithOneParameter ( )
1718 {
18- Connection . RegisterTableFunction < int > ( "demo" , ( parameters ) =>
19+ Connection . RegisterTableFunction < int > ( "demo" , async ( parameters ) =>
1920 {
2021 var value = parameters [ 0 ] . GetValue < int > ( ) ;
2122
@@ -33,119 +34,157 @@ public void RegisterTableFunctionWithOneParameter()
3334 }
3435
3536 [ Fact ]
36- public void RegisterTableFunctionWithTwoParameterTwoColumns ( )
37+ public void RegisterTableFunctionWithTwoParameters ( )
3738 {
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 ) =>
5140 {
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 > ( ) ;
6243
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" ) ) ;
7645
77- return new TableFunction ( new List < ColumnInfo > ( )
46+ var request = new SearchRepositoriesRequest ( term )
7847 {
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+ } ;
8750
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 ) ;
9152
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-
10653 return new TableFunction ( new List < ColumnInfo > ( )
10754 {
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 ) ;
11061 } , ( item , writers , rowIndex ) =>
11162 {
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 ) ;
11369 } ) ;
11470
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 ( ) ;
11972 }
12073
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+ //}
151190}
0 commit comments