edgedb / edgedb-go

The official Go client library for EdgeDB
https://pkg.go.dev/github.com/edgedb/edgedb-go
Apache License 2.0
168 stars 11 forks source link

Query builder #182

Open fmoor opened 3 years ago

fmoor commented 3 years ago

Something better than string concatenation for dynamic query construction.

diogox commented 2 years ago

Hi :wave:

Is the string concatenation approach safe? I would assume "sql injection"-like attacks are possible?

elprans commented 2 years ago

Is the string concatenation approach safe?

In general, it is not. Like with SQL, interpolating unsanitized user input into EdgeQL queries might lead to "EdgeQL injection". Thus, you must always pass input as query arguments.

That said, composing queries from non-arbitrary string pieces is just fine, e.g:

        type Result struct {
                Title   string `edgedb:"title"`
        }
        var results []Result

        query := "SELECT Article { title }"
        args := make([]interface{}, 0)

        if pattern != "" {
            query = query + " FILTER title LIKE <str>$0"
            args = append(args, pattern)
        }

        err = client.Query(ctx, query, &results, args...)

Naturally, this isn't the most ergonomic approach, so we are looking to build generated clients to compose queries in a type-safe manner.

diogox commented 2 years ago

Ah, alright. Weird though. I tried using the arguments in insertions and it didn't work:

insert users::User {
  email := $0,
  username := $1,
  hashedPassword := $2,
  type := $3
}

Using this in a Query call yields the edgedb.QueryError: missing a type cast before the parameter error.

Not even possible to use it in Execute, because it doesn't take arguments.

Which is annoying, because Query forces you to pass in a pointer to a slice to read the result, even if you don't want the result.

elprans commented 2 years ago

missing a type cast before the parameter means that you must explicitly specify the types of query arguments with a cast:

insert users::User {
  email := <str>$0,
  username := <str>$1,
  hashedPassword := <str>$2,
  type := <str>$3
}
diogox commented 2 years ago

Cool, thanks for letting me know!

A better API, or something like sqlc, would be amazing.

Will be following the project, edgedb looks great! :)

paulm17 commented 2 years ago

@diogox thanks for creating this issue. Due to the lack of documentation I also followed the string concatenation method from looking at the test files and I also came across the issue that Execute does not take any arguments either.

Still I solved my issues by following the advice from @elprans.

Definitely looking forward to the query builder, when it becomes available. 👍

endigma commented 2 years ago

As opposed to sqlc, perhaps code-generating the SDK similar to entgo.io would be possible? ent is in my opinion the strongest golang ORM purely based on the fully typed CRUD and hooks and etc. Not all of this would be possible given edgeDB is not entirely the same concept, but following in the footsteps of ent and creating a codegenned-SDK from the source schema instead of from documents like sqlc would be a big difference in my opinion.