Found some bugs with the connection creation modal. Need to work on the parsing and such with regex.
106 lines
2.4 KiB
Go
106 lines
2.4 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/Azpect3120/Web-Database-Viewer/internal/templates"
|
|
"github.com/gin-contrib/sessions"
|
|
"github.com/gin-gonic/gin"
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
func TableTree(c *gin.Context) string {
|
|
session := sessions.Default(c)
|
|
connections_bytes, ok := session.Get("connections").([]byte)
|
|
current, ok := session.Get("current").(string)
|
|
if !ok {
|
|
fmt.Println("No connections found")
|
|
return ""
|
|
}
|
|
|
|
var connections map[string]string
|
|
if err := json.Unmarshal(connections_bytes, &connections); err != nil {
|
|
fmt.Println(err)
|
|
return ""
|
|
}
|
|
|
|
url := connections[current]
|
|
|
|
tree, err := generateTree(url)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return ""
|
|
}
|
|
|
|
return templates.TableTree(tree)
|
|
}
|
|
|
|
// Generate the tree of the database tables
|
|
func generateTree(url string) (map[string][]string, error) {
|
|
conn, err := sql.Open("postgres", url)
|
|
if err != nil {
|
|
return map[string][]string{}, err
|
|
}
|
|
defer conn.Close()
|
|
|
|
tree, err := tableList(conn)
|
|
if err != nil {
|
|
return map[string][]string{}, err
|
|
}
|
|
|
|
if err := fillColumns(conn, tree); err != nil {
|
|
return map[string][]string{}, err
|
|
}
|
|
|
|
return tree, nil
|
|
}
|
|
|
|
// Return a map with the keys being the table names and the values
|
|
// being blank which can be later used to store the columns.
|
|
func tableList(conn *sql.DB) (map[string][]string, error) {
|
|
rows, err := conn.Query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE';")
|
|
if err != nil {
|
|
return map[string][]string{}, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
tree := make(map[string][]string)
|
|
for rows.Next() {
|
|
var table string
|
|
if err := rows.Scan(&table); err != nil {
|
|
return map[string][]string{}, err
|
|
}
|
|
tree[table] = []string{}
|
|
}
|
|
|
|
return tree, nil
|
|
}
|
|
|
|
// Fill the columns of the tables in the tree using the keys found
|
|
// in the tableList function.
|
|
//
|
|
// For now, the only data stored is the
|
|
// column name, but in the future this could be expanded to store
|
|
// datatype, constraints, primary keys, relationship, etc.
|
|
func fillColumns(conn *sql.DB, tree map[string][]string) error {
|
|
for table := range tree {
|
|
rows, err := conn.Query(fmt.Sprintf("SELECT column_name FROM information_schema.columns WHERE table_name = '%s';", table))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rows.Close()
|
|
|
|
for rows.Next() {
|
|
var column string
|
|
if err := rows.Scan(&column); err != nil {
|
|
return err
|
|
}
|
|
tree[table] = append(tree[table], column)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|