package advsql import ( "log" "reflect" ) type structure struct { TypeName string Fields []field } type field struct { FieldName string FieldType reflect.Type } func makeFieldUsingReflect(reflectField reflect.StructField) field { return field{ FieldName: reflectField.Name, FieldType: reflectField.Type, } } func compareStructures(first, second *structure) bool { // compare names if first.TypeName != second.TypeName { log.Println("different names") return false } firstFieldAmount, secondFieldAmount := len(first.Fields), len(second.Fields) // compare field amounts if firstFieldAmount != secondFieldAmount { log.Println("different field amounts") return false } // compare fields for i := 0; i < firstFieldAmount; i++ { firstField, secondField := first.Fields[i], second.Fields[i] if !compareFields(firstField, secondField) { log.Println("different field:", firstField, secondField) return false } } return true } func compareFields(first, second field) bool { t1, t2 := first.FieldType, second.FieldType // check if field names are equal fieldNamesEqual := first.FieldName == second.FieldName // exceptions for default comparison switch true { case checkBoth(first, second, isString, isByteSlice): fallthrough case isInt(first) && isInt(second): fallthrough case isUint(first) && isUint(second): return fieldNamesEqual default: return t1 == t2 } } // TypeCheckFunc represents any function for type checking between Go and DB type TypeCheckFunc func(field) bool // checks if both check functions apply to either of the fields func checkBoth(first, second field, firstCheck, secondCheck TypeCheckFunc) bool { return firstCheck(first) && secondCheck(second) || firstCheck(second) && secondCheck(first) } func isString(field field) bool { return field.FieldType.Kind() == reflect.String } func isInt(field field) bool { return field.FieldType.Kind() == reflect.Int || field.FieldType.Kind() == reflect.Int64 } func isUint(field field) bool { return field.FieldType.Kind() == reflect.Uint || field.FieldType.Kind() == reflect.Uint64 } func isByteSlice(field field) bool { return field.FieldType.Kind() == reflect.Slice && field.FieldType.Elem().Kind() == reflect.Uint8 }