Doctor: ORM via Code Generation
In Go, there are several ways to get the expressiveness of generic operations:
interfaces, reflection and code generation. I have a previous ORM attempt that
used reflection and some interface trickery to get a reasonably expressive API,
but ran into issues with the ability for developers to customize the Mapper's.
This library is composed of a code generation library and supporting libraries
that allows developers to create and maintain code to talk to SQL databases.
Description
Doctor reads in files with the extension gp (Go Prototype) then writes out multiple
Go files that implement Object Relational Mapper functionality. You define structs,
but with the special keywords table, mixin, and subrecord. Doctor will use those keywords
to generate code for your library. Table's are the top-level construct, mixins have
their fields and functions duplicated for each table they are used in. Finally,
subrecords have their fields added to each table they're used in, but share the
same struct definition.
Current Status
Doctor is currently about the same level of features as my previous attempt, and
starting to eclipse it. Current schedule looks like:
- Complete migrate for sqlite
- Port migrate to MySQL and Postgres
- Write unit tests for InnerJoin, OuterJoin, & JoinSQL
- Create more tables in the forum example for testing HasOne/BelongsTo
- Port blog example tests to forum for test consolidation
- Work on Travis CI test runner
- Subrecords (schema, queries, Include)
- Include'ing other tables
- Arbitrary Pluck
- Save should recurse into unsaved children
- Row locking
- Documentation site + godoc
- More tests?
Future Features
I can't put everything in one release, I want to get this library working
so I can start using it. Then I can start to add and remove things as I
need them or they are revealed to be bad ideas. I would like to add
dirty checking for fields so only fields that need to be updated will be
updated. There's probably only going to be a single migration library
version when I release the first version, so I should go back and build
a (nearly) zero-downtime version.
Things to Complain About
-
Doctor generates a lot of code currently, on the order of 110x the input.
-
Advanced SQL features aren't well supported.
-
Documentation could always be better.
-
Non integer primary keys.
-
Composite primary keys.
-
More column defintion keys for tags.
Example Model Definition
package forum
type User table {
ID int
FirstName, LastName string
Email, password string
Website string
BanExpiration *time.Time
Signature string `type:"text"`
Posts []Post `column:"AuthorID"`
Threads []Thread `column:"AuthorID"`
postLikes []postLike
LikedPosts []Post `through:"postLikes"`
}
type Forum table {
ID int
Name string
Rules string `type:"text"`
}
type Thread table {
ID int
Title string
AuthorID int
Author User
Posts []Post
Locked bool
}
type Post table {
ID int
ThreadID int
Thread Thread
Number int
AuthorID int
Author User
ParentID *int
Parent *Post
Body string `type:"text"`
likes []postLike
Likers []User `through:"likes"`
}
type postLike table {
ID int
PostID int
UserID int
}