Azpect3120 9820ecac64 FEAT: Some work on the tree
Found some bugs with the connection creation modal. Need to work on the
parsing and such with regex.
2024-08-09 13:50:07 -07:00

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
}