diff --git a/README.md b/README.md index 04e5fca..7323771 100644 --- a/README.md +++ b/README.md @@ -1047,6 +1047,43 @@ exists, err := jet.Pilot(db).Exists() exists, err := models.Pilots(db, Where("id=?", 5)).Exists() ``` +### Enums + +If your MySQL or Postgres tables use enums we will generate constants that hold their values +that you can use in your queries. For example: + +``` +CREATE TYPE workday AS ENUM('monday', 'tuesday', 'wednesday', 'thursday', 'friday'); + +CREATE TABLE event_one ( + id serial PRIMARY KEY NOT NULL, + name VARCHAR(255), + day workday NOT NULL +); +``` + +An enum type defined like the above, being used by a table, will generate the following enums: + +``` +const ( + WorkdayMonday = "monday" + WorkdayTuesday = "tuesday" + WorkdayWednesday = "wednesday" + WorkdayThursday = "thursday" + WorkdayFriday = "friday" +) +``` + +For Postgres we use `enum type name + title cased` value to generate the const variable name. +For MySQL we use `table name + column name + title cased value` to generate the const variable name. + +Note: If your enum holds a value we cannot parse correctly due, to non-alphabet characters for example, +it may not be generated. In this event, you will receive errors in your generated tests because +the value randomizer in the test suite does not know how to generate valid enum values. You will +still be able to use your generated library, and it will still work as expected, but the only way +to get the tests to pass in this event is to either use a parsable enum value or use a regular column +instead of an enum. + ## FAQ #### Won't compiling models for a huge database be very slow? diff --git a/randomize/randomize.go b/randomize/randomize.go index 0da7aed..5f14a8b 100644 --- a/randomize/randomize.go +++ b/randomize/randomize.go @@ -158,6 +158,16 @@ func randDate(s *Seed) time.Time { // If canBeNull is true: // The value has the possibility of being null or non-zero at random. func randomizeField(s *Seed, field reflect.Value, fieldType string, canBeNull bool) error { + if strings.HasPrefix(fieldType, "enum") { + enum, err := randEnumValue(fieldType) + if err != nil { + return err + } + + field.Set(reflect.ValueOf(enum)) + return nil + } + kind := field.Kind() typ := field.Type() @@ -604,3 +614,12 @@ func getVariableRandValue(s *Seed, kind reflect.Kind, typ reflect.Type) interfac return nil } + +func randEnumValue(enum string) (string, error) { + vals := strmangle.ParseEnumVals(enum) + if vals == nil || len(vals) == 0 { + return "", fmt.Errorf("unable to parse enum string: %s", enum) + } + + return vals[rand.Intn(len(vals)-1)], nil +} diff --git a/randomize/randomize_test.go b/randomize/randomize_test.go index fbd3255..6f117b7 100644 --- a/randomize/randomize_test.go +++ b/randomize/randomize_test.go @@ -144,3 +144,28 @@ func TestRandomizeField(t *testing.T) { } } } + +func TestRandEnumValue(t *testing.T) { + t.Parallel() + + enum1 := "enum.workday('monday','tuesday')" + enum2 := "enum('monday','tuesday')" + + r1, err := randEnumValue(enum1) + if err != nil { + t.Error(err) + } + + if r1 != "monday" && r1 != "tuesday" { + t.Errorf("Expected monday or tueday, got: %q", r1) + } + + r2, err := randEnumValue(enum2) + if err != nil { + t.Error(err) + } + + if r2 != "monday" && r2 != "tuesday" { + t.Errorf("Expected monday or tueday, got: %q", r2) + } +} diff --git a/testdata/postgres_test_schema.sql b/testdata/postgres_test_schema.sql index c046d29..151c699 100644 --- a/testdata/postgres_test_schema.sql +++ b/testdata/postgres_test_schema.sql @@ -1,3 +1,24 @@ +CREATE TYPE workday AS ENUM('monday', 'tuesday', 'wednesday', 'thursday', 'friday'); +CREATE TYPE faceyface AS ENUM('angry', 'hungry', 'bitter'); + +CREATE TABLE event_one ( + id serial PRIMARY KEY NOT NULL, + name VARCHAR(255), + day workday NOT NULL +); + +CREATE TABLE event_two ( + id serial PRIMARY KEY NOT NULL, + name VARCHAR(255), + day workday NOT NULL +); + +CREATE TABLE facey ( + id serial PRIMARY KEY NOT NULL, + name VARCHAR(255), + face faceyface NOT NULL +); + CREATE TABLE magic ( id serial PRIMARY KEY NOT NULL, id_two serial NOT NULL,