github.com/eden-framework/sqlx@v0.0.2/postgresqlconnector/schemas.go (about) 1 package postgresqlconnector 2 3 import ( 4 "regexp" 5 "strings" 6 7 "github.com/eden-framework/sqlx" 8 "github.com/eden-framework/sqlx/builder" 9 ) 10 11 func toInterfaces(list ...string) []interface{} { 12 s := make([]interface{}, len(list)) 13 for i, v := range list { 14 s[i] = v 15 } 16 return s 17 } 18 19 func dbFromInformationSchema(db sqlx.DBExecutor) *sqlx.Database { 20 d := db.D() 21 22 dbName := d.Name 23 dbSchema := d.Schema 24 tableNames := d.Tables.TableNames() 25 26 d = sqlx.NewDatabase(dbName).WithSchema(dbSchema) 27 28 tableColumnSchema := SchemaDatabase.T(&ColumnSchema{}).WithSchema("information_schema") 29 columnSchemaList := make([]ColumnSchema, 0) 30 31 tableSchema := "public" 32 if d.Schema != "" { 33 tableSchema = d.Schema 34 } 35 36 stmt := builder.Select(tableColumnSchema.Columns.Clone()).From(tableColumnSchema, 37 builder.Where( 38 builder.And( 39 tableColumnSchema.F("TABLE_SCHEMA").Eq(tableSchema), 40 tableColumnSchema.F("TABLE_NAME").In(toInterfaces(tableNames...)...), 41 ), 42 ), 43 ) 44 45 err := db.QueryExprAndScan(stmt, &columnSchemaList) 46 if err != nil { 47 panic(err) 48 } 49 50 for _, columnSchema := range columnSchemaList { 51 table := d.Table(columnSchema.TABLE_NAME) 52 if table == nil { 53 table = builder.T(columnSchema.TABLE_NAME) 54 d.AddTable(table) 55 } 56 col := builder.Col(columnSchema.COLUMN_NAME) 57 table.AddCol(col) 58 } 59 60 if tableColumnSchema.Columns.Len() != 0 { 61 tableIndexSchema := SchemaDatabase.T(&IndexSchema{}) 62 63 indexList := make([]IndexSchema, 0) 64 65 err = db.QueryExprAndScan( 66 builder.Select(tableIndexSchema.Columns.Clone()). 67 From( 68 tableIndexSchema, 69 builder.Where( 70 builder.And( 71 tableIndexSchema.F("TABLE_SCHEMA").Eq(tableSchema), 72 tableIndexSchema.F("TABLE_NAME").In(toInterfaces(tableNames...)...), 73 ), 74 ), 75 ), 76 &indexList, 77 ) 78 79 if err != nil { 80 panic(err) 81 } 82 83 for _, indexSchema := range indexList { 84 table := d.Table(indexSchema.TABLE_NAME) 85 86 key := &builder.Key{} 87 key.Name = indexSchema.INDEX_NAME[len(table.Name)+1:] 88 key.Method = strings.ToUpper(regexp.MustCompile(`USING ([^ ]+)`).FindString(indexSchema.INDEX_DEF)[6:]) 89 key.IsUnique = strings.Index(indexSchema.INDEX_DEF, "UNIQUE") > -1 90 91 fields := regexp.MustCompile(`\([^\)]+\)`).FindString(indexSchema.INDEX_DEF) 92 if len(fields) > 0 { 93 fields = fields[1 : len(fields)-1] 94 } 95 key.Columns, _ = table.Cols(strings.Split(fields, ", ")...) 96 table.AddKey(key) 97 } 98 } 99 100 return d 101 } 102 103 var SchemaDatabase = sqlx.NewDatabase("INFORMATION_SCHEMA") 104 105 func init() { 106 SchemaDatabase.Register(&ColumnSchema{}) 107 SchemaDatabase.Register(&IndexSchema{}) 108 } 109 110 type ColumnSchema struct { 111 TABLE_SCHEMA string `db:"table_schema"` 112 TABLE_NAME string `db:"table_name"` 113 COLUMN_NAME string `db:"column_name"` 114 } 115 116 func (ColumnSchema) TableName() string { 117 return "columns" 118 } 119 120 type IndexSchema struct { 121 TABLE_SCHEMA string `db:"schemaname"` 122 TABLE_NAME string `db:"tablename"` 123 INDEX_NAME string `db:"indexname"` 124 INDEX_DEF string `db:"indexdef"` 125 } 126 127 func (IndexSchema) TableName() string { 128 return "pg_indexes" 129 }