github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/db/db_common/schema_metadata.go (about) 1 package db_common 2 3 import ( 4 "github.com/turbot/steampipe/pkg/utils" 5 "golang.org/x/exp/maps" 6 "regexp" 7 "sort" 8 "strings" 9 ) 10 11 func NewSchemaMetadata() *SchemaMetadata { 12 return &SchemaMetadata{ 13 Schemas: map[string]map[string]TableSchema{}, 14 } 15 } 16 17 // SchemaMetadata is a struct to represent the schema of the database 18 type SchemaMetadata struct { 19 // map {schemaname, {map {tablename -> tableschema}} 20 Schemas map[string]map[string]TableSchema 21 // the name of the temporary schema 22 TemporarySchemaName string 23 } 24 25 // TableSchema contains the details of a single table in the schema 26 type TableSchema struct { 27 // map columnName -> columnSchema 28 Columns map[string]ColumnSchema 29 Name string 30 FullName string 31 Schema string 32 Description string 33 } 34 35 // ColumnSchema contains the details of a single column in a table 36 type ColumnSchema struct { 37 ID string 38 Name string 39 NotNull bool 40 Type string 41 Default string 42 Description string 43 } 44 45 // GetSchemas returns all foreign schema names 46 func (m *SchemaMetadata) GetSchemas() []string { 47 var schemas []string 48 for schema := range m.Schemas { 49 schemas = append(schemas, schema) 50 } 51 sort.Strings(schemas) 52 return schemas 53 } 54 55 // GetTablesInSchema returns a lookup of all foreign tables in a given foreign schema 56 func (m *SchemaMetadata) GetTablesInSchema(schemaName string) map[string]struct{} { 57 return utils.SliceToLookup(maps.Keys(m.Schemas[schemaName])) 58 } 59 60 // IsSchemaNameValid verifies that the given string is a valid pgsql schema name 61 func IsSchemaNameValid(name string) (bool, string) { 62 var message string 63 64 // start with the basics 65 66 // cannot be blank 67 if len(strings.TrimSpace(name)) == 0 { 68 message = "Schema name cannot be blank." 69 return false, message 70 } 71 72 // there should not be whitespaces or dashes 73 if strings.Contains(name, " ") || strings.Contains(name, "-") { 74 message = "Schema name should not contain whitespaces or dashes." 75 return false, message 76 } 77 78 // cannot start with `pg_` 79 if strings.HasPrefix(name, "pg_") { 80 message = "Schema name should not start with `pg_`" 81 return false, message 82 } 83 84 // as per https://www.postgresql.org/docs/9.2/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS 85 // not allowing $ sign, since it is not allowed in standard sql 86 regex := regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*`) 87 88 if !regex.MatchString(name) { 89 message = "Schema name string contains invalid pattern." 90 return false, message 91 } 92 93 // let's limit the length to 63 94 if len(name) > 63 { 95 message = "Schema name length should not exceed 63 characters." 96 return false, message 97 } 98 99 return true, message 100 }