GithubHelp home page GithubHelp logo

softstonedevelop / gedaq Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 1.95 MB

ORM Gedaq is generator for obtaining and mapping data from the database.

License: MIT License

C# 99.87% PowerShell 0.13%
ado-net code-generation mapping npgsql orm roslyn-generator sql micro-orm csharp dotnet

gedaq's People

Contributors

softstonedevelop avatar

Watchers

 avatar  avatar

gedaq's Issues

Generated methods 'Return type'

Return type:

  • Enumerable
  • Single(throw exception if not have result or more than one)
  • SingleOrDefault(throw exception if have more than one result)
  • First(throw exception if nothing to return)
  • FirstOrDefault

Now we have only IEnumrable or IAsyncEnumrable for async version.

Add a new optional parameter "methodParametrName" for ParametrAttribute

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"

AsPartInterface

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(...
}

Explicit cast parameters

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.

Remove duplicate syntax

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.

Write a test generator

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.

Support Fromat for Query

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");
}

Replace "yield return" with a custom enumerator

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.