softstonedevelop / gedaq Goto Github PK
View Code? Open in Web Editor NEWORM Gedaq is generator for obtaining and mapping data from the database.
License: MIT License
ORM Gedaq is generator for obtaining and mapping data from the database.
License: MIT License
If the class is partial, then generate methods in it instead of creating a new class.
Return type:
Now we have only IEnumrable or IAsyncEnumrable for async version.
When calling methods, it is not clear what the parameters are if the parameters are unnamed, for example, positional parameters in PostgreSQL. There are also cases when we do not want the name of the parameter passed to the method to be different from the name of the parameter in the command.
Therefore, you need to add a new optional parameter to the attribute - "methodParametrName"
If and when it will be available.
dotnet/runtime#82326
See: Gedaq.DbConnection.GeneratorsBatch.DbBatchCommand.cs
and Gedaq.DbConnection.Helpers.DbGeneratorHelper.cs
Add info about generated methods as part of the interface.
For example, this can be useful if we want to separate commands and queries:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
publlic partial interface IPersonRepository : ICommandPersonRepository, IQueryPersonRepository
{
}
publlic partial interface ICommandPersonRepository
{
}
publlic partial interface IQueryPersonRepository
{
}
public partial class PersonRepository : IPersonRepository
{
[Query(
@"
SELECT
p.id,
p.name
FROM person p
",
"GetAllPerson",
typeof(Person),
MethodType.Async,
QueryType.Read,
asPartInterface: typeof(IQueryPersonRepository)
)]
private GetAllPersonConfig()
{
}
[Query(
@"
INSERT INTO person(
id
)
VALUES (
$1
)
",
"AddPerson",
typeof(Person),
MethodType.Async,
QueryType.NonQuery,
asPartInterface: typeof(ICommandPersonRepository)
),
Parametr(typeof(int), position: 1, methodParametrName: "id")
]
private GetAllPersonConfig()
{
}
}
void SomewhereInCode(
ICommandPersonRepository commands,
IQueryPersonRepository queries
)
{
//commands.AddPersonAsync(...
//queries.GetAllPersonAsync(...
}
It's mostly useful for enums. When in the code it is Enum
and in the database it is short
for example.
Now:
[Query(@"
UPDATE public.table_with_enum
SET
status = $1
WHERE
id = $2
;
",
"SetStatus",
methodType: MethodType.Async,
sourceType: Gedaq.Npgsql.Enums.SourceType.Connection,
queryType: QueryType.NonQuery,
accessModifier: AccessModifier.Public
),
Parametr(typeof(short), position: 1, methodParametrName: "status"),
Parametr(typeof(long), position: 2, methodParametrName: "id")
]
private void ConfigSetStatus()
{
}
public SomeMethod()
{
await SetStatus(connection: connection, status: (short)CurrentStatus.New, id: 1);
}
Excpect:
[Query(@"
UPDATE public.table_with_enum
SET
status = $1
WHERE
id = $2
;
",
"SetStatus",
methodType: MethodType.Async,
sourceType: Gedaq.Npgsql.Enums.SourceType.Connection,
queryType: QueryType.NonQuery,
accessModifier: AccessModifier.Public
),
Parametr(typeof(short), position: 1, methodParametrName: "status", methodParametrType: typeof(CurrentStatus)),
Parametr(typeof(long), position: 2, methodParametrName: "id")
]
private void ConfigSetStatus()
{
}
public SomeMethod()
{
await SetStatus(connection: connection, status: CurrentStatus.New, id: 1);
}
Add methodParameterType
optional parameter.
Instead of:
[Query(
@"
SELECT
p.id,
p.firstname,
~StartInner::Identification:id~
i.id,
~StartInner::Country:id~
c.id,
c.name,
~EndInner::Country~
i.typename,
~EndInner::Identification~
p.middlename,
p.lastname
FROM dbconnectionperson p
LEFT JOIN dbconnectionidentification i ON i.id = p.identification_id
LEFT JOIN dbconnectioncountry c ON c.id = i.country_id
WHERE p.id != {1} AND p.id != {0}
ORDER BY p.id ASC
",
"NpgsqlToClass2",
typeof(Person),
Gedaq.Common.Enums.MethodType.Async | Gedaq.Common.Enums.MethodType.Sync
)]
[QueryFormat("NpgsqlToClass2", 1, "condition")]
[QueryFormat("NpgsqlToClass2", 0)]
public void Method()
{
//...
}
write like this:
[Query(
@"
SELECT
p.id,
p.firstname,
~StartInner::Identification:id~
i.id,
~StartInner::Country:id~
c.id,
c.name,
~EndInner::Country~
i.typename,
~EndInner::Identification~
p.middlename,
p.lastname
FROM dbconnectionperson p
LEFT JOIN dbconnectionidentification i ON i.id = p.identification_id
LEFT JOIN dbconnectioncountry c ON c.id = i.country_id
WHERE p.id != {1} AND p.id != {0}
ORDER BY p.id ASC
",
"NpgsqlToClass2",
typeof(Person),
Gedaq.Common.Enums.MethodType.Async | Gedaq.Common.Enums.MethodType.Sync
),
QueryFormat(1, "condition"),
QueryFormat(0)
]
public void Method()
{
//...
}
Everything in the same group belongs to the request. The same goes for batch requests.
Eliminates method name(NpgsqlToClass2
) duplication.
In now generator combine method name and provider name for output filename. This is not enough unique names because method name can be duplicate between classes.
In order to be sure that all providers work, you need to check the generation on all supported types of providers: both for DbConnection and for specific attributes and specific providers.
And these are essentially the same tests with slight differences. When choosing between "trying to wrap it all in inheritance or composition" or "write a unit test generator" I choose the latter.
If generation was cancelled. This will improve generator performance.
https://www.postgresql.org/docs/current/dml-returning.html
On the Gedaq side, we need to recognize "returning" and issue an appropriate mapping.
Batch, Query, Parametrs
Not all queries can be parameterized. For example, in Postgresql the query "create database" does not support parameterization.
CREATE DATABASE MyDbName TEMPLATE template0 CONNECTION LIMIT = -1;
Need add new feature:
[Query(@"
CREATE DATABASE {0} TEMPLATE template0 CONNECTION LIMIT = -1;
",
"CreateDatabase",
methodType: Gedaq.Common.Enums.MethodType.Sync,
sourceType: Gedaq.Npgsql.Enums.SourceType.Connection,
queryType: Gedaq.Common.Enums.QueryType.NonQuery
)]
[QueryFormat(position: 0)]
private void Method(DbConnection connection)
{
connection.CreateDatabase("MyDbName");
}
When there will be a request from users
Because only in postgresql this is not required (the transaction is opened in connection and not set in command), but in other databases it is necessary.
After receiving the first element from the enumeration, we know exactly how many elements there will be. Therefore, we can use this for methods like ToList().
Also, "yield return" has some overhead.
Compare the refactoring result with the original in a performance test.
This is start for create nuget(https://digitalhouseblog.wordpress.com/2019/08/22/how-to-make-a-nuget-package-for-c/).
This change improve nuget experience. Same parser like in postgre server. This means we can get return aliases in all cases(return, subquery, func).
Add parameter to attribute what specify database types.
There is no point in having static methods in a non-static partial class. Such a class itself implies that we want to access instance methods. For example, if we register such a class in the DI container, then we need the instance methods.
When .NET 8 realesed - replace String.Format on CompositeFormat.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.