tomasfabian / ksqlDB.RestApi.Client-DotNet

ksqlDb.RestApi.Client is a C# LINQ-enabled client API for issuing and consuming ksqlDB push and pull queries and executing statements.
MIT License
93 stars 24 forks source link

GUID in Contains/IN #45

Closed Markauto closed 1 year ago

Markauto commented 1 year ago

Hi,

Hope you are well! Loving the library thanks for creating it!

For my class I am using GUID's as an id field and when I want to do a contains/IN its adding the GUID's but without the ' around the values. For example: SELECT * FROM Pages WHERE Id IN (77d6e8b9-e733-4465-b429-1a6e115daad7, aa9ab7f0-59cb-4e9a-b2a5-40cf5de3c6ab); This should be: SELECT * FROM Pages WHERE Id IN ('77d6e8b9-e733-4465-b429-1a6e115daad7', 'aa9ab7f0-59cb-4e9a-b2a5-40cf5de3c6ab');

Think this is because in the VisitConstant method in the KsqlVisitor class its failing this check:

if (inputValue != null && !this.isInContainsScope && (type.IsClass || type.IsStruct() || type.IsDictionary()))

because its in a contains scope, so the value doesn't get handled by the CreateKSqlValue().ExtractValue logic and therefore never gets the ' around it.

Not sure what the best fix for this would be.

Thanks Mark

My classes:

public record Page(Guid Id, string Name, string Colour);
 public class GameEventData : Record
{
    public GameEventData(Guid id, string colour, string tdm, string gameCategory, string name)
    {
        this.Id = id;
        this.Colour = colour;
        this.TDM = tdm;
        this.GameCategory = gameCategory;
        this.Name = name;
    }

    [Key]
    public Guid Id { get; set; }
    public string Colour { get; set; }
    public string TDM { get; set; }
    public string GameCategory { get; set; }
    public string Name { get; set; }
}

The Table:

 context.CreateTableStatement(TableName)
            .With(new CreationMetadata { KafkaTopic = this.streamHandler.Topic })
            .As<GameEventData>().GroupBy(c => c.Id).Select(window => new
            {
                Id = window.Key,
                Name =
                    window.LatestByOffset(gameEventData => gameEventData.Name),
                Colour = window.LatestByOffset(gameEventData =>
                    gameEventData.Colour)
            });

Then the pull query:

 public async Task<IEnumerable<Page>> GetPages(IEnumerable<Guid> ids)
    {
context.CreatePullQuery<Page>(TableName).Where(page =>ids.Contains(page.Id));
return await result.GetManyAsync().ToListAsync();
}
tomasfabian commented 1 year ago

Hi @Markauto, I've just released a hot fix 3.0.1.

Thank you for reporting the issue and for your appreciation, too!

Regards Tomas.

Markauto commented 1 year ago

Excellent Thanks Tomas!