Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Drivers/ColumnMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class ColumnMapping(
Func<int, string>? readerArrayFn = null,
string? usingDirective = null,
Func<string, bool, bool, string>? writerFn = null,
string? convertFunc = null,
Func<string, string>? convertFunc = null,
string? sqlMapper = null,
string? sqlMapperImpl = null)
{
Expand All @@ -20,7 +20,7 @@ public class ColumnMapping(
public Func<int, string>? ReaderArrayFn { get; } = readerArrayFn;
public string? UsingDirective { get; } = usingDirective;
public Func<string, bool, bool, string>? WriterFn { get; } = writerFn;
public string? ConvertFunc { get; } = convertFunc;
public Func<string, string>? ConvertFunc { get; } = convertFunc;
public string? SqlMapper { get; } = sqlMapper;
public string? SqlMapperImpl { get; } = sqlMapperImpl;
}
9 changes: 4 additions & 5 deletions Drivers/DbDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ public abstract class DbDriver
"NpgsqlCidr",
];

protected const string IntTo32 = "Convert.ToInt32";
protected const string IntTo64 = "Convert.ToInt64";


public abstract Dictionary<string, ColumnMapping> ColumnMappings { get; }

Expand Down Expand Up @@ -339,11 +336,13 @@ public string GetIdColumnType(Query query)
public virtual string[] GetLastIdStatement(Query query)
{
var idColumnType = GetIdColumnType(query);
var convertFunc = ColumnMappings[idColumnType].ConvertFunc ?? throw new InvalidOperationException($"ConvertFunc is missing for id column type {idColumnType}");
var convertFunc = ColumnMappings[idColumnType].ConvertFunc ??
throw new InvalidOperationException($"ConvertFunc is missing for id column type {idColumnType}");
var convertFuncCall = convertFunc(Variable.Result.AsVarName());
return
[
$"var {Variable.Result.AsVarName()} = await {Variable.Command.AsVarName()}.ExecuteScalarAsync();",
$"return {convertFunc}({Variable.Result.AsVarName()});"
$"return {convertFuncCall};"
];
}

Expand Down
4 changes: 2 additions & 2 deletions Drivers/MySqlConnectorDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public partial class MySqlConnectorDriver(
{ "bigint", new() }
},
ordinal => $"reader.GetInt64({ordinal})",
convertFunc: IntTo64
convertFunc: x => $"Convert.ToInt64{x}"
),
["byte"] = new ColumnMapping(
new()
Expand Down Expand Up @@ -99,7 +99,7 @@ public partial class MySqlConnectorDriver(
{ "mediumint", new() }
},
ordinal => $"reader.GetInt32({ordinal})",
convertFunc: IntTo32
convertFunc: x => $"Convert.ToInt32{x}"
),
["double"] = new(
new()
Expand Down
11 changes: 7 additions & 4 deletions Drivers/NpgsqlDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public NpgsqlDriver(
},
readerFn: ordinal => $"reader.GetInt64({ordinal})",
readerArrayFn: ordinal => $"reader.GetFieldValue<long[]>({ordinal})",
convertFunc: IntTo64
convertFunc: x => $"Convert.ToInt64({x})"
),
["byte[]"] = new(
new()
Expand Down Expand Up @@ -81,7 +81,8 @@ public NpgsqlDriver(
{ "uuid", new() }
},
readerFn: ordinal => $"reader.GetFieldValue<Guid>({ordinal})",
readerArrayFn: ordinal => $"reader.GetFieldValue<Guid[]>({ordinal})"
readerArrayFn: ordinal => $"reader.GetFieldValue<Guid[]>({ordinal})",
convertFunc: x => $"Guid.Parse({x}?.ToString())"
),
["TimeSpan"] = new(
new()
Expand Down Expand Up @@ -126,7 +127,8 @@ public NpgsqlDriver(
{ "int2", new() }
},
readerFn: ordinal => $"reader.GetInt16({ordinal})",
readerArrayFn: ordinal => $"reader.GetFieldValue<short[]>({ordinal})"
readerArrayFn: ordinal => $"reader.GetFieldValue<short[]>({ordinal})",
convertFunc: x => $"Convert.ToInt16({x})"
),
["int"] = new(
new()
Expand All @@ -137,7 +139,8 @@ public NpgsqlDriver(
{ "serial", new() }
},
readerFn: ordinal => $"reader.GetInt32({ordinal})",
readerArrayFn: ordinal => $"reader.GetFieldValue<int[]>({ordinal})"
readerArrayFn: ordinal => $"reader.GetFieldValue<int[]>({ordinal})",
convertFunc: x => $"Convert.ToInt32({x})"
),
["float"] = new(
new()
Expand Down
2 changes: 1 addition & 1 deletion Drivers/SqliteDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public partial class SqliteDriver(
{ "integernotnulldefaultunixepoch", new() }
},
ordinal => $"reader.GetInt32({ordinal})",
convertFunc: IntTo32
convertFunc: x => $"Convert.ToInt32({x})"
),
["decimal"] = new(
new()
Expand Down
12 changes: 10 additions & 2 deletions docs/04_Postgres.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
<details>
<summary>:execlastid - Implementation</summary>

Implemented via a `RETURNING` clause, allowing the `INSERT` command to return the newly created id, which can be of any
data type that can have a unique constraint.
Implemented via a `RETURNING` clause, allowing the `INSERT` command to return the newly created id.
The data types that can be used as id data types for this annotation are:
1. uuid
2. bigint
3. integer
4. smallint (less recommended due to small id range, but possible)

```sql
INSERT INTO tab1 (field1, field2) VALUES ('a', 1) RETURNING id_field;
```
</details>

<details>
Expand Down
7 changes: 3 additions & 4 deletions docs/06_Sqlite.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
<summary>:execlastid - Implementation</summary>

## :execlastid - Implementation
Implemented via a `RETURNING` clause, allowing the `INSERT` command to return the newly created id, which can be of any
data type that can have a unique constraint.

Implemented via a `RETURNING` clause, allowing the `INSERT` command to return the newly created id.
Only integer data type is supported as id for this annotation.
```sql
INSERT INTO tab1 (field1, field2) VALUES ('a', 1) RETURNING id_field;
```

</details>

<details>
Expand Down
2 changes: 1 addition & 1 deletion examples/NpgsqlDapperExample/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Author
};
public class Book
{
public required long Id { get; init; }
public required Guid Id { get; init; }
public required string Name { get; init; }
public required long AuthorId { get; init; }
public string? Description { get; init; }
Expand Down
16 changes: 8 additions & 8 deletions examples/NpgsqlDapperExample/QuerySql.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,14 +361,14 @@
private const string CreateBookSql = "INSERT INTO books (name, author_id) VALUES (@name, @author_id) RETURNING id";
public class CreateBookRow
{
public required long Id { get; init; }
public required Guid Id { get; init; }
};
public class CreateBookArgs
{
public required string Name { get; init; }
public required long AuthorId { get; init; }
};
public async Task<long> CreateBook(CreateBookArgs args)
public async Task<Guid> CreateBook(CreateBookArgs args)
{
var queryParams = new Dictionary<string, object?>();
queryParams.Add("name", args.Name);
Expand All @@ -377,7 +377,7 @@
{
using (var connection = new NpgsqlConnection(ConnectionString))
{
return await connection.QuerySingleAsync<long>(CreateBookSql, queryParams);
return await connection.QuerySingleAsync<Guid>(CreateBookSql, queryParams);
}
}

Expand All @@ -386,7 +386,7 @@
throw new System.InvalidOperationException("Transaction is provided, but its connection is null.");
}

return await this.Transaction.Connection.QuerySingleAsync<long>(CreateBookSql, queryParams, transaction: this.Transaction);
return await this.Transaction.Connection.QuerySingleAsync<Guid>(CreateBookSql, queryParams, transaction: this.Transaction);
}

private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name ";
Expand All @@ -399,7 +399,7 @@
{
if (this.Transaction == null)
{
using (var connection = NpgsqlDataSource.Create(ConnectionString))

Check warning on line 402 in examples/NpgsqlDapperExample/QuerySql.cs

View workflow job for this annotation

GitHub Actions / End-to-End Tests

Possible null reference argument for parameter 'connectionString' in 'NpgsqlDataSource NpgsqlDataSource.Create(string connectionString)'.
{
using (var command = connection.CreateCommand(ListAllAuthorsBooksSql))
{
Expand All @@ -407,7 +407,7 @@
{
var result = new List<ListAllAuthorsBooksRow>();
while (await reader.ReadAsync())
result.Add(new ListAllAuthorsBooksRow { Author = new Author { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2) }, Book = new Book { Id = reader.GetInt64(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
result.Add(new ListAllAuthorsBooksRow { Author = new Author { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2) }, Book = new Book { Id = reader.GetFieldValue<Guid>(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
return result;
}
}
Expand All @@ -424,7 +424,7 @@
{
var result = new List<ListAllAuthorsBooksRow>();
while (await reader.ReadAsync())
result.Add(new ListAllAuthorsBooksRow { Author = new Author { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2) }, Book = new Book { Id = reader.GetInt64(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
result.Add(new ListAllAuthorsBooksRow { Author = new Author { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2) }, Book = new Book { Id = reader.GetFieldValue<Guid>(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
return result;
}
}
Expand All @@ -440,7 +440,7 @@
{
if (this.Transaction == null)
{
using (var connection = NpgsqlDataSource.Create(ConnectionString))

Check warning on line 443 in examples/NpgsqlDapperExample/QuerySql.cs

View workflow job for this annotation

GitHub Actions / End-to-End Tests

Possible null reference argument for parameter 'connectionString' in 'NpgsqlDataSource NpgsqlDataSource.Create(string connectionString)'.
{
using (var command = connection.CreateCommand(GetDuplicateAuthorsSql))
{
Expand Down Expand Up @@ -487,7 +487,7 @@
{
if (this.Transaction == null)
{
using (var connection = NpgsqlDataSource.Create(ConnectionString))

Check warning on line 490 in examples/NpgsqlDapperExample/QuerySql.cs

View workflow job for this annotation

GitHub Actions / End-to-End Tests

Possible null reference argument for parameter 'connectionString' in 'NpgsqlDataSource NpgsqlDataSource.Create(string connectionString)'.
{
using (var command = connection.CreateCommand(GetAuthorsByBookNameSql))
{
Expand All @@ -496,7 +496,7 @@
{
var result = new List<GetAuthorsByBookNameRow>();
while (await reader.ReadAsync())
result.Add(new GetAuthorsByBookNameRow { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2), Book = new Book { Id = reader.GetInt64(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
result.Add(new GetAuthorsByBookNameRow { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2), Book = new Book { Id = reader.GetFieldValue<Guid>(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
return result;
}
}
Expand All @@ -514,7 +514,7 @@
{
var result = new List<GetAuthorsByBookNameRow>();
while (await reader.ReadAsync())
result.Add(new GetAuthorsByBookNameRow { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2), Book = new Book { Id = reader.GetInt64(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
result.Add(new GetAuthorsByBookNameRow { Id = reader.GetInt64(0), Name = reader.GetString(1), Bio = reader.IsDBNull(2) ? null : reader.GetString(2), Book = new Book { Id = reader.GetFieldValue<Guid>(3), Name = reader.GetString(4), AuthorId = reader.GetInt64(5), Description = reader.IsDBNull(6) ? null : reader.GetString(6) } });
return result;
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/NpgsqlDapperExample/request.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"name": "books"
},
"type": {
"name": "bigserial"
"name": "uuid"
}
},
{
Expand Down Expand Up @@ -33003,7 +33003,7 @@
"name": "books"
},
"type": {
"name": "bigserial"
"name": "uuid"
},
"originalName": "id"
}
Expand Down
14 changes: 7 additions & 7 deletions examples/NpgsqlDapperExample/request.message
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
2
postgresql%examples/config/postgresql/schema.sql"$examples/config/postgresql/query.sqlb‡
examples/NpgsqlDapperExamplecsharpÈ{"debugRequest":true,"generateCsproj":true,"namespaceName":"NpgsqlDapperExampleGen","overrides":[{"column":"GetPostgresFunctions:max_integer","csharp_type":{"notNull":false,"type":"int"}},{"column":"GetPostgresFunctions:max_varchar","csharp_type":{"notNull":false,"type":"string"}},{"column":"GetPostgresFunctions:max_timestamp","csharp_type":{"notNull":true,"type":"DateTime"}},{"column":"*:c_json_string_override","csharp_type":{"notNull":false,"type":"string"}},{"column":"*:c_macaddr8","csharp_type":{"notNull":false,"type":"string"}}],"targetFramework":"net8.0","useDapper":true}*
./dist/LocalRunner¼å public"publicƒ
./dist/LocalRunner·å public"‹publicƒ
authors)
id0ÿÿÿÿÿÿÿÿÿR authorsb  bigserial&
name0ÿÿÿÿÿÿÿÿÿR authorsbtext#
bio0ÿÿÿÿÿÿÿÿÿR authorsbtextº
books'
id0ÿÿÿÿÿÿÿÿÿRbooksb  bigserial$
bio0ÿÿÿÿÿÿÿÿÿR authorsbtextµ
books"
id0ÿÿÿÿÿÿÿÿÿRbooksbuuid$
name0ÿÿÿÿÿÿÿÿÿRbooksbtext5
author_id0ÿÿÿÿÿÿÿÿÿRbooksb
pg_catalogint8)
Expand Down Expand Up @@ -10260,10 +10260,10 @@ WHERE id = ANY($1::BIGINT []) AND name = ANY($2::TEXT [])GetAuthorsByIdsAndNam
id0ÿÿÿÿÿÿÿÿÿR authorsb  bigserialzid",
name0ÿÿÿÿÿÿÿÿÿR authorsbtextzname"(
bio0ÿÿÿÿÿÿÿÿÿR authorsbtextzbio**& 0ÿÿÿÿÿÿÿÿÿb
pg_catalogint8ˆ* 0ÿÿÿÿÿÿÿÿÿbtextˆ: query.sql¡
pg_catalogint8ˆ* 0ÿÿÿÿÿÿÿÿÿbtextˆ: query.sqlœ
@INSERT INTO books (name, author_id) VALUES ($1, $2) RETURNING id
CreateBook :execlastid"+
id0ÿÿÿÿÿÿÿÿÿRbooksb  bigserialzid*62
CreateBook :execlastid"&
id0ÿÿÿÿÿÿÿÿÿRbooksbuuidzid*62
name0ÿÿÿÿÿÿÿÿÿRpublicbooksbtextzname*KG
author_id0ÿÿÿÿÿÿÿÿÿRpublicbooksbpg_catalog.int8z author_id: query.sqlBbooks®
ÂSELECT
Expand Down
2 changes: 1 addition & 1 deletion examples/NpgsqlDapperLegacyExample/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class Author
};
public class Book
{
public long Id { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
public long AuthorId { get; set; }
public string Description { get; set; }
Expand Down
Loading
Loading