// SetDefaultSettings sets the default values for the settings func SetDefaultSettings(genName string, defaultSettings schema.Generator, s *schema.Schema) schema.Generator { settings, _ := s.Generators.Get(genName) settings.SetNX("databaseName", defaultSettings.Get("databaseName").(string)) settings.SetNX("schemaName", defaultSettings.Get("schemaName").(string)) settings.SetNX("tableName", defaultSettings.Get("tableName").(string)) settings.SetNX("roleName", defaultSettings.Get("roleName").(string)) // convert []interface to []string grants := settings.GetWithDefault("grants", defaultSettings.Get("grants").([]string)) grantsI, ok := grants.([]interface{}) grantsS := make([]string, 0) if ok { for _, t := range grantsI { grantsS = append(grantsS, t.(string)) } } else { grantsS = grants.([]string) } settings.Set("grants", grantsS) return settings }
// DefineConstraints creates constraints definition for tables func DefineConstraints(settings schema.Generator, s *schema.Schema) ([]byte, error) { primaryKeyConstraint := "" primaryKey := settings.Get("primaryKey") if primaryKey != nil { pmi := primaryKey.([]interface{}) if len(pmi) > 0 { sl := make([]string, len(pmi)) for i, pm := range pmi { sl[i] = stringext.ToFieldName(pm.(string)) } primaryKeyConstraint = fmt.Sprintf( "ALTER TABLE %q.%q ADD PRIMARY KEY (%q) NOT DEFERRABLE INITIALLY IMMEDIATE;\n", settings.Get("schemaName"), settings.Get("tableName"), strings.Join(sl, ", "), ) primaryKeyConstraint = fmt.Sprintf("-------------------------------\n-- Primary key structure for table %s\n-- ----------------------------\n%s", settings.Get("tableName"), primaryKeyConstraint, ) } } uniqueKeyConstraints := "" uniqueKeys := settings.Get("uniqueKeys") if uniqueKeys != nil { ukci := uniqueKeys.([]interface{}) if len(ukci) > 0 { for _, ukc := range ukci { ukcs := ukc.([]interface{}) ukcsps := make([]string, len(ukcs)) for i, ukc := range ukcs { ukcsps[i] = stringext.ToFieldName(ukc.(string)) } keyName := fmt.Sprintf( "%s_%s_%s", stringext.ToFieldName("key"), stringext.ToFieldName(settings.Get("tableName").(string)), strings.Join(ukcsps, "_"), ) uniqueKeyConstraints += fmt.Sprintf( "ALTER TABLE %q.%q ADD CONSTRAINT %q UNIQUE (\"%s\") NOT DEFERRABLE INITIALLY IMMEDIATE;\n", settings.Get("schemaName"), settings.Get("tableName"), keyName, strings.Join(ukcsps, "\", \""), ) } uniqueKeyConstraints = fmt.Sprintf("-------------------------------\n-- Unique key structure for table %s\n-- ----------------------------\n%s", settings.Get("tableName"), uniqueKeyConstraints, ) } } foreignKeyConstraints := "" foreignKeys := settings.Get("foreignKeys") if foreignKeys != nil { fkci := foreignKeys.([]interface{}) if len(fkci) > 0 { for _, fkc := range fkci { fkcs := fkc.([]interface{}) localField := stringext.ToFieldName(fkcs[0].(string)) refFields := strings.Split(fkcs[1].(string), ".") if len(refFields) != 3 { return nil, fmt.Errorf("need schemaName.tableName.fieldName") } keyName := fmt.Sprintf( "%s_%s_%s", stringext.ToFieldName("fkey"), stringext.ToFieldName(settings.Get("tableName").(string)), localField, ) foreignKeyConstraints += fmt.Sprintf( "ALTER TABLE %q.%q ADD CONSTRAINT %q FOREIGN KEY (\"%s\") REFERENCES %s.%s (%s) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE;\n", settings.Get("schemaName"), settings.Get("tableName"), keyName, localField, stringext.ToFieldName(refFields[0]), // first item schema name stringext.ToFieldName(refFields[1]), // second item table name stringext.ToFieldName(refFields[2]), // third item field name ) foreignKeyConstraints = fmt.Sprintf("-------------------------------\n-- Foreign keys structure for table %s\n-- ----------------------------\n%s", settings.Get("tableName"), foreignKeyConstraints, ) } } } return clean([]byte(primaryKeyConstraint + uniqueKeyConstraints + foreignKeyConstraints)), nil }
// GenerateSQLField creates a definition line for a given coloumn func GenerateSQLField(settings schema.Generator, s *schema.Schema) (res string) { propertyName := s.Title schemaName := settings.Get("schemaName").(string) tableName := settings.Get("tableName").(string) property := s fieldName := stringext.ToFieldName(propertyName) // transpiled version of property if property.Title != "" { fieldName = stringext.ToFieldName(property.Title) } fieldType := "" // will hold the type for coloumn switch strings.ToLower(property.Type.(string)) { case "boolean": fieldType = "BOOLEAN" case "string": switch property.Format { case "date-time": fieldType = "TIMESTAMP (6) WITH TIME ZONE" case "UUID": fieldType = "UUID" default: typeName := "TEXT" if property.MaxLength > 0 { // if schema defines a max length, no need to use text typeName = fmt.Sprintf("VARCHAR (%d)", property.MaxLength) } fieldType = fmt.Sprintf("%s COLLATE \"default\"", typeName) } case "number": fieldType = "NUMERIC" switch property.Format { case "int64", "uint64": fieldType = "BIGINT" case "integer", "int", "int32", "uint", "uint32": fieldType = "INTEGER" case "int8", "uint8", "int16", "uint16": fieldType = "SMALLINT" case "float32", "float64": fieldType = "NUMERIC" } case "any": panic("should specify type") case "array": panic("array not supported") case "object", "config": // TODO implement embedded struct table creation res = "" case "null": res = "" case "error": res = "" case "custom": res = "" default: panic("unknown field") } // override if it is an enum field if len(property.Enum) > 0 { fieldType = fmt.Sprintf( "%q.\"%s_%s_enum\"", schemaName, stringext.ToFieldName(tableName), stringext.ToFieldName(propertyName), ) } res = fmt.Sprintf( "%q %s %s %s %s,", // first, name comes fieldName, // then type of the coloumn fieldType, // generate default value if exists generateDefaultValue(schemaName, fieldName, tableName, property), // generate not null statement, if required generateNotNull(s, propertyName), // generate validators generateCheckStatements(tableName, fieldName, property), ) return res }