Protect the `.fields' variable state from partial-initialization timing
issues.
As gorm warms state and makes `.GetStructFields' calls, they lead to a long
deferred function in model_struct.go. Then the deferred function calls
`Scope.Fields', leading to another `.GetStructFields' call.. cyclically.
Once information is cached the cycling ends.
This extra rule evicts incorrect/suspiciously short fields information.
Symptom of incorrect internal state ocurring can manifest as invalid
insert SQL statement errors generated during `DB.Save', e.g.:
INSERT INTO "your_table" DEFAULT VALUES RETURNING "your_table"."id"
This is why we refresh if nil or only a single field (usually is the ID field).
Included is a unit-test which triggers the scenario and prove that it is
fixed.
This commit allows you to pass a string or an existing database
connection as the source for gorm. The dialect is still required
because a) there is no common reference to it as far as i know, and
b) gorm allows the dialect to differ from the driver. So, for the sake
of simplicity, you still have to specity the dialect.
This is useful if you have an existing transaction, but still
want to use gorm to format your queries.
This is dependent on the defintion of DB in pkg database/sql having
the field 'dsn', which is the database source, obtained via reflect.
This commit adds more ways of specifying selects:
-) You can now pass in a []string. This is mostly for convenience,
since you may want to dynamically create a list of fields to be
selected.
-) You can now use variables. This is important because a select
could take user input. For example, finding a MAX between a record
and a given number could be easily done using select, and then
you don't have to process anything in backend logic. This is also
necessary to use postgres text search capabilities (which actaully
play nicely with the rest of gorm).
-) You can now chain select calls. This could be useful in
conjunction with gorm's scopes functionality.