Closed aarondl closed 6 years ago
Thanks for bringing this to my attention. Totally did not intend to misconstrue what Sqlboiler was capable of.
Let me know if you think this is accurate. I don't know everything about SQLBoiler, so I want to make sure I'm not mis-stating things.
Where(personTable.Age + " > ?", 30)
, which could lead
to typos and type-incompatibility. If you change the type of a column, that
code won't fail until it's triggered by a test or in production.
This is how I would write it:
Workflow and Templates:
Generated API style:
Type safety:
interface{}
and developer written strings for clauses where conditions are involved (where, inner join). Where(models.PersonColumns.Age + " > ?", 30)
which can lead to typos and type-incompatibility. If you change the type of a column this code will not fail until it's used in a test or production. Only a name change will cause this to fail (unless you completely replace the templates with something type safe).Relationship support:
Database support:
Optimization:
Obviously because you are trying to "sell" your library I don't mind what you do. This is simply how I would write this section but it may be that you wouldn't want to include the last 3 points because like as the first 3 put Gnorm in a favorable light, the opposite is true for the last 3 since those are areas where SQLBoiler is very strong. My main goal here was to remove the errors in the facts with this issue though a true comparison would probably include all 6 points. I leave it to you to do as you will with what I've written here and trust that at the very least we've removed all the factual errors.
Also note I haven't seen any example of how Gnorm does it's 100% type safe where clause. Can you point out an example? I'm genuinely curious as an "ORM person" haha.
On a final note, it's too bad you had gripes with sqlboiler that we couldn't attempt to solve together. I saw your posts on reddit and even asked you about it once, and the difference just didn't seem large enough to me (because you could replace templates in sqlboiler with whatever you wanted, even 100% type safe code if you wanted). I don't recall ever being reached out to about changing sqlboiler up in a way that would make it work for you. Clearly I'm biased but it would have been great to work together on a solution instead of have two solutions that are so incredibly similar. At the end of the day they're just templating engines and sqlboiler just has more opinions on what comes out of the box whereas gnorm has more fine grained control over generated code. Anyway, thanks for addressing this issue.
I really appreciate the fact checking. I definitely don't want to be misleading about SQLBoiler.
So, the type safety in Gnorm is just generating the right wrapper code for each type. So, for example, if you have a table with an integer column, we generate a struct with an int field, of course. But we also generate an "IntField" variable for each column like this: https://github.com/gnormal/postgres-go/blob/master/example/gnorm/books/books.go#L34
An IntField has a bunch of methods on it that return a WhereClause value that generates the right SQL for that type. So for example, you'd do like bks, err := books.Query(db, books.PagesCol.Equals(20))
. You can't typo the name of the column, because it's built into the generated code, and you can't pass it the wrong type, because the column value has methods that only accept the right type.
This is not to say that you can't still intentionally do the wrong thing if you want to generate your own WhereClause... but that is difficult and would be glaringly obvious at the call site.
There's more I could do to make it even more safe, but this seems like a good middle ground, where all the common errors are avoided without making the code too convoluted.
Yeah, when I was looking at SQLBoiler last year, I didn't realize one could swap out the templates. That definitely would have been an easier solution than writing my own tool :)
I honestly don't remember you reaching out, but I have a terrible memory. I hope I was nice, at least. :) . When I was looking at writing Gnorm, we had been using xo at work, and I was just annoyed at how it did everything, so I basically wrote Gnorm in response to xo. I looked around at alternatives, but SQLBoiler's docs focused mostly on the built-in templates, which produced code that I didn't like, so I didn't look much further into it.
I copied all but 5 and 6... 5 because I have a blanket statement at the bottom about DB support, and 6 because, as you said, I haven't benchmarked gnorm and neither has anyone else... and that's mostly because whatever benchmark you do is entirely dependent on what the templates generate.
https://github.com/gnormal/gnorm/blob/master/site/content/gnorm-vs/_index.md
Of these 1 and 3 are not true, as of version 3.0 you can generate whatever file types you want using sqlboiler using custom templates, and column names, relationship names (3.0 only), and table names are all generated as well which users can use as constants which will change when the database changes to ensure compiler errors. I'd appreciate if this text was rectified to be factually accurate as of the latest released version. Thanks!