Skip to content

Commit 21a03f0

Browse files
vkuttypCopilot
andcommitted
Add SqlDataTable.ToList<T>() - Codable-style row mapping
Reflection-based mapper that matches column names to public settable properties (case-insensitive), converting SqlValue to the correct CLR type. Handles nullable types, bool, int, long, float, double, decimal, string, DateTime, Guid, byte[]. Null SQL values leave the property at its default. Also fix ToMarkdownTable to use AsString() instead of record ToString(). Bump to v1.2.4. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 92d42ab commit 21a03f0

6 files changed

Lines changed: 60 additions & 5 deletions

File tree

src/SqlDotnetty.Core/SqlDataTable.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Reflection;
12
using System.Text;
23

34
namespace CosmoSQLClient.Core;
@@ -31,6 +32,60 @@ public static SqlDataTable From(string name, IReadOnlyList<SqlRow> rows)
3132
public SqlValue Cell(int row, int col) => Rows[row][col];
3233
public SqlValue Cell(int row, string col) => Rows[row][col];
3334

35+
/// <summary>
36+
/// Maps each row to an instance of <typeparamref name="T"/> by matching column names
37+
/// to public settable properties (case-insensitive). Works like Dapper / Swift Codable.
38+
/// </summary>
39+
public List<T> ToList<T>() where T : new()
40+
{
41+
var props = typeof(T)
42+
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
43+
.Where(p => p.CanWrite)
44+
.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase);
45+
46+
// Pre-resolve column index → property mapping once
47+
var map = Columns
48+
.Select((col, idx) => (idx, prop: props.GetValueOrDefault(col.Name)))
49+
.Where(x => x.prop is not null)
50+
.ToList();
51+
52+
var result = new List<T>(Rows.Count);
53+
foreach (var row in Rows)
54+
{
55+
var obj = new T();
56+
foreach (var (idx, prop) in map)
57+
SetProperty(obj, prop!, row[idx]);
58+
result.Add(obj);
59+
}
60+
return result;
61+
}
62+
63+
private static void SetProperty(object obj, PropertyInfo prop, SqlValue value)
64+
{
65+
if (value.IsNull) return; // leave default for nulls
66+
67+
var t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
68+
69+
object? v = Type.GetTypeCode(t) switch
70+
{
71+
TypeCode.Boolean => value.AsBool(),
72+
TypeCode.SByte => (sbyte?)value.AsInt(),
73+
TypeCode.Int16 => (short?)value.AsInt(),
74+
TypeCode.Int32 => (int?)value.AsInt(),
75+
TypeCode.Int64 => value.AsInt(),
76+
TypeCode.Single => (float?)value.AsDouble(),
77+
TypeCode.Double => value.AsDouble(),
78+
TypeCode.Decimal => value.AsDecimal(),
79+
TypeCode.String => value.AsString(),
80+
TypeCode.DateTime => value.AsDate(),
81+
_ when t == typeof(Guid) => value.AsGuid(),
82+
_ when t == typeof(byte[]) => value.AsBytes(),
83+
_ => value.AsString()
84+
};
85+
86+
if (v is not null) prop.SetValue(obj, v);
87+
}
88+
3489
/// <summary>Render as a Markdown table string.</summary>
3590
public string ToMarkdownTable()
3691
{

src/SqlDotnetty.Core/SqlDotnetty.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<Nullable>enable</Nullable>
99

1010
<PackageId>CosmoSQLClient.Core</PackageId>
11-
<Version>1.2.3</Version>
11+
<Version>1.2.4</Version>
1212
<Authors>Veeran Puthumkara</Authors>
1313
<Description>Shared core types and interfaces for CosmoSQLClient — a unified .NET database driver for MSSQL, PostgreSQL, MySQL and SQLite using DotNetty.</Description>
1414
<PackageTags>sql;mssql;postgres;mysql;sqlite;database;driver;dotnetty;nio</PackageTags>

src/SqlDotnetty.MsSql/SqlDotnetty.MsSql.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<Nullable>enable</Nullable>
2121

2222
<PackageId>CosmoSQLClient.MsSql</PackageId>
23-
<Version>1.2.3</Version>
23+
<Version>1.2.4</Version>
2424
<Authors>Veeran Puthumkara</Authors>
2525
<Description>Microsoft SQL Server driver for CosmoSQLClient — TDS 7.4 wire protocol from scratch using DotNetty. Supports TLS, Windows/SQL auth, stored procedures and connection pooling.</Description>
2626
<PackageTags>sql;mssql;sqlserver;tds;database;driver;dotnetty;nio</PackageTags>

src/SqlDotnetty.MySql/SqlDotnetty.MySql.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<Nullable>enable</Nullable>
2121

2222
<PackageId>CosmoSQLClient.MySql</PackageId>
23-
<Version>1.2.3</Version>
23+
<Version>1.2.4</Version>
2424
<Authors>Veeran Puthumkara</Authors>
2525
<Description>MySQL driver for CosmoSQLClient — MySQL v10 wire protocol using DotNetty. Supports mysql_native_password, caching_sha2_password auth and connection pooling.</Description>
2626
<PackageTags>sql;mysql;mariadb;database;driver;dotnetty;nio</PackageTags>

src/SqlDotnetty.Postgres/SqlDotnetty.Postgres.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<Nullable>enable</Nullable>
2121

2222
<PackageId>CosmoSQLClient.Postgres</PackageId>
23-
<Version>1.2.3</Version>
23+
<Version>1.2.4</Version>
2424
<Authors>Veeran Puthumkara</Authors>
2525
<Description>PostgreSQL driver for CosmoSQLClient — PostgreSQL v3 wire protocol using DotNetty. Supports SCRAM-SHA-256 auth, TLS and connection pooling.</Description>
2626
<PackageTags>sql;postgres;postgresql;database;driver;dotnetty;nio</PackageTags>

src/SqlDotnetty.Sqlite/SqlDotnetty.Sqlite.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<Nullable>enable</Nullable>
1717

1818
<PackageId>CosmoSQLClient.Sqlite</PackageId>
19-
<Version>1.2.3</Version>
19+
<Version>1.2.4</Version>
2020
<Authors>Veeran Puthumkara</Authors>
2121
<Description>SQLite driver for CosmoSQLClient — wraps Microsoft.Data.Sqlite behind the unified ISqlDatabase interface with connection pooling support.</Description>
2222
<PackageTags>sql;sqlite;database;driver;dotnetty;nio</PackageTags>

0 commit comments

Comments
 (0)