github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/boilingcore/text_helpers.go (about) 1 package boilingcore 2 3 import ( 4 "strings" 5 6 "github.com/volatiletech/sqlboiler/v4/drivers" 7 "github.com/volatiletech/strmangle" 8 ) 9 10 // txtNameToOne creates the local and foreign function names for 11 // one-to-many and one-to-one relationships, where local is the side with 12 // the foreign key. 13 // 14 // = many-to-one 15 // users - videos : user_id 16 // users - videos : producer_id 17 // 18 // fk == table = user.Videos | video.User 19 // fk != table = user.ProducerVideos | video.Producer 20 // 21 // = many-to-one 22 // industries - industries : industry_id 23 // industries - industries : parent_id 24 // 25 // fk == table = industry.Industries | industry.Industry 26 // fk != table = industry.ParentIndustries | industry.Parent 27 // 28 // = one-to-one 29 // users - videos : user_id 30 // users - videos : producer_id 31 // 32 // fk == table = user.Video | video.User 33 // fk != table = user.ProducerVideo | video.Producer 34 // 35 // = one-to-one 36 // industries - industries : parent_id 37 // 38 // fk == table = industry.Industry | industry.Industry 39 // fk != table = industry.ParentIndustry | industry.Industry 40 func txtNameToOne(fk drivers.ForeignKey) (localFn, foreignFn string) { 41 fkColumnTrimmedSuffixes := strmangle.Singular(trimSuffixes(fk.Column)) 42 fkNotTableName := fkColumnTrimmedSuffixes != strmangle.Singular(fk.ForeignTable) 43 singularForeignTable := strmangle.Singular(fk.ForeignTable) 44 45 if fkColumnTrimmedSuffixes == singularForeignTable { 46 foreignFn = strmangle.TitleCase(strmangle.Singular(fk.Table) + "_" + fkColumnTrimmedSuffixes) 47 if fk.Column != singularForeignTable { 48 foreignFn = strmangle.TitleCase(fkColumnTrimmedSuffixes) 49 } 50 } else if fkColumnTrimmedSuffixes == fk.Column { 51 foreignFn = strmangle.TitleCase(fkColumnTrimmedSuffixes + "_" + strmangle.Singular(fk.ForeignTable)) 52 } else { 53 foreignFn = strmangle.TitleCase(fkColumnTrimmedSuffixes) 54 } 55 56 if fkNotTableName { 57 localFn = strmangle.TitleCase(fkColumnTrimmedSuffixes) 58 } 59 60 plurality := strmangle.Plural 61 if fk.Unique { 62 plurality = strmangle.Singular 63 } 64 localFn += strmangle.TitleCase(plurality(fk.Table)) 65 66 return localFn, foreignFn 67 } 68 69 // txtNameToMany creates the local and foreign function names for 70 // many-to-many relationships where there are two foreign keys involved. 71 // 72 // The output of the foreign key is the name for that side of the relationship. 73 // 74 // | tags | | tags_videos | | videos | 75 // | id | | tag_id, video_id | | id | 76 // 77 // In this setup the lhs is the tag_id foreign key, and so the lhsFn will 78 // refer to "how to name the lhs" which in this case should be tags. And 79 // videos for the rhs. 80 // 81 // cases: 82 // sponsors - contests 83 // sponsor_id contest_id 84 // fk == table = sponsor.Contests | contest.Sponsors 85 // 86 // sponsors - contests 87 // wiggle_id jiggle_id 88 // fk != table = sponsor.JiggleSponsors | contest.WiggleContests 89 // 90 // industries - industries 91 // industry_id mapped_industry_id 92 // fk == table = industry.Industries 93 // fk != table = industry.MappedIndustryIndustry 94 func txtNameToMany(lhs, rhs drivers.ForeignKey) (lhsFn, rhsFn string) { 95 lhsKey := strmangle.Singular(trimSuffixes(lhs.Column)) 96 rhsKey := strmangle.Singular(trimSuffixes(rhs.Column)) 97 98 if lhsKey != strmangle.Singular(lhs.ForeignTable) { 99 lhsFn = strmangle.TitleCase(lhsKey) 100 } 101 lhsFn += strmangle.TitleCase(strmangle.Plural(lhs.ForeignTable)) 102 103 if rhsKey != strmangle.Singular(rhs.ForeignTable) { 104 rhsFn = strmangle.TitleCase(rhsKey) 105 } 106 rhsFn += strmangle.TitleCase(strmangle.Plural(rhs.ForeignTable)) 107 108 return lhsFn, rhsFn 109 } 110 111 // usesPrimitives checks to see if relationship between two models (ie the foreign key column 112 // and referred to column) both are primitive Go types we can compare or assign with == and = 113 // in a template. 114 func usesPrimitives(tables []drivers.Table, table, column, foreignTable, foreignColumn string) bool { 115 local := drivers.GetTable(tables, table) 116 foreign := drivers.GetTable(tables, foreignTable) 117 118 col := local.GetColumn(column) 119 foreignCol := foreign.GetColumn(foreignColumn) 120 121 return isPrimitive(col.Type) && isPrimitive(foreignCol.Type) 122 } 123 124 var identifierSuffixes = []string{"_id", "_uuid", "_guid", "_oid"} 125 126 // trimSuffixes from the identifier 127 func trimSuffixes(str string) string { 128 ln := len(str) 129 for _, s := range identifierSuffixes { 130 str = strings.TrimSuffix(str, s) 131 if len(str) != ln { 132 break 133 } 134 } 135 136 return str 137 } 138 139 func isPrimitive(typ string) bool { 140 switch typ { 141 // Numeric 142 case "int", "int8", "int16", "int32", "int64": 143 return true 144 case "uint", "uint8", "uint16", "uint32", "uint64": 145 return true 146 case "float32", "float64": 147 return true 148 case "byte", "rune", "string": 149 return true 150 } 151 152 return false 153 } 154 155 func isNullPrimitive(typ string) bool { 156 switch typ { 157 // Numeric 158 case "null.Int", "null.Int8", "null.Int16", "null.Int32", "null.Int64": 159 return true 160 case "null.Uint", "null.Uint8", "null.Uint16", "null.Uint32", "null.Uint64": 161 return true 162 case "null.Float32", "null.Float64": 163 return true 164 case "null.Byte", "null.String": 165 return true 166 } 167 168 return false 169 } 170 171 // convertNullToPrimitive takes a type name and returns the underlying primitive type name X if it is a `null.X`, 172 // otherwise it returns the input value unchanged 173 func convertNullToPrimitive(typ string) string { 174 if isNullPrimitive(typ) { 175 return strings.ToLower(strings.Split(typ, ".")[1]) 176 } 177 return typ 178 }