Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cmd/postgresql_test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func main() {
Schema: "public",

// SSL configuration
SSLConfig: models.PostgreSQLSSLConfig{
SSLConfig: models.SSLConfig{
Mode: "prefer",
InsecureSkipVerify: true,
},
Expand Down Expand Up @@ -80,7 +80,11 @@ func main() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

db, err := repo.Connect(ctx, config)
dbConfig := models.DatabaseConfig{
Type: models.DatabaseTypePostgreSQL,
PostgreSQL: config,
}
db, err := repo.Connect(ctx, dbConfig)
if err != nil {
log.Fatalf("❌ Failed to connect to PostgreSQL: %v", err)
}
Expand Down
33 changes: 26 additions & 7 deletions cmd/sql-graph-cli/commands/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Supports both MySQL and PostgreSQL databases with database-specific optimization
}

// Database type and connection flags
cmd.Flags().StringVar(&dbType, "db-type", "mysql", "Database type: mysql, postgresql")
cmd.Flags().StringVar(&dbType, "db-type", "mysql", "Database type: mysql, postgresql, oracle")
cmd.Flags().StringVar(&host, "host", "localhost", "Database host")
cmd.Flags().IntVar(&port, "port", 0, "Database port (0 = auto-detect: MySQL=3306, PostgreSQL=5432)")
cmd.Flags().StringVar(&username, "username", "", "Database username")
Expand Down Expand Up @@ -199,7 +199,7 @@ func runAnalyze(_ *cobra.Command, opts analyzeOptions) error {
var config models.DatabaseConfig
switch opts.DBType {
case models.DatabaseTypeMySQL:
config = &models.MySQLConfig{
config = models.DatabaseConfig{Type: models.DatabaseTypeMySQL, MySQL: &models.MySQLConfig{
Host: opts.Host,
Port: opts.Port,
Username: opts.Username,
Expand Down Expand Up @@ -232,10 +232,10 @@ func runAnalyze(_ *cobra.Command, opts analyzeOptions) error {
},
},
},
}
}}

case models.DatabaseTypePostgreSQL:
config = &models.PostgreSQLConfig{
config = models.DatabaseConfig{Type: models.DatabaseTypePostgreSQL, PostgreSQL: &models.PostgreSQLConfig{
Host: opts.Host,
Port: opts.Port,
Username: opts.Username,
Expand All @@ -245,7 +245,7 @@ func runAnalyze(_ *cobra.Command, opts analyzeOptions) error {
ConnectionMode: models.ConnectionModeExisting,

// PostgreSQL-specific settings
SSLConfig: models.PostgreSQLSSLConfig{
SSLConfig: models.SSLConfig{
Mode: opts.SSLMode,
CertFile: opts.SSLCertFile,
KeyFile: opts.SSLKeyFile,
Expand Down Expand Up @@ -279,7 +279,26 @@ func runAnalyze(_ *cobra.Command, opts analyzeOptions) error {
},
},
},
}}

case models.DatabaseTypeOracle:
port := opts.Port
if port == 0 {
port = 1521
}
config = models.DatabaseConfig{Type: models.DatabaseTypeOracle, Oracle: &models.OracleConfig{
Host: opts.Host,
Port: port,
ServiceName: opts.Database,
Username: opts.Username,
Password: opts.Password,
Security: models.SecurityConfig{
ReadOnly: true,
ConnectionTimeout: opts.ConnectionTimeout,
QueryTimeout: opts.QueryTimeout,
MaxConnections: opts.MaxConnections,
},
}}

default:
return fmt.Errorf("unsupported database type: %s", opts.DBType)
Expand Down Expand Up @@ -360,7 +379,7 @@ func outputSummary(result *models.UniversalDatabaseAnalysisResult, outputFile st
fmt.Fprintf(&output, " Database Type: %s\n", strings.ToUpper(string(result.DatabaseType)))
fmt.Fprintf(&output, " Database: %s@%s:%d/%s\n",
result.DatabaseInfo.User, result.DatabaseInfo.Host,
result.DatabaseInfo.Port, result.DatabaseInfo.Database)
result.DatabaseInfo.Port, result.DatabaseInfo.Database)
fmt.Fprintf(&output, " Server Version: %s\n", result.DatabaseInfo.Version)
}
fmt.Fprintf(&output, " Processing Time: %v\n", result.ProcessingDuration)
Expand Down Expand Up @@ -392,7 +411,7 @@ func outputSummary(result *models.UniversalDatabaseAnalysisResult, outputFile st
schemaInfo = fmt.Sprintf(" (%s)", table.Schema)
}
fmt.Fprintf(&output, " %-20s%s - %d rows, %d columns\n",
table.Name, schemaInfo, table.EstimatedRows, len(table.Columns))
table.Name, schemaInfo, table.EstimatedRows, len(table.Columns))

// Show column details for first few tables
if len(result.SchemaAnalysis.Tables) <= 3 && len(table.Columns) > 0 {
Expand Down
29 changes: 24 additions & 5 deletions cmd/sql-graph-cli/commands/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ This command provides immediate feedback on:
}

// Database type and connection flags
cmd.Flags().StringVar(&dbType, "db-type", "mysql", "Database type: mysql, postgresql")
cmd.Flags().StringVar(&dbType, "db-type", "mysql", "Database type: mysql, postgresql, oracle")
cmd.Flags().StringVar(&host, "host", "localhost", "Database host")
cmd.Flags().IntVar(&port, "port", 0, "Database port (0 = auto-detect: MySQL=3306, PostgreSQL=5432)")
cmd.Flags().StringVar(&username, "username", "", "Database username")
Expand Down Expand Up @@ -160,7 +160,7 @@ func runTest(opts testOptions) error {
var config models.DatabaseConfig
switch opts.DBType {
case models.DatabaseTypeMySQL:
config = &models.MySQLConfig{
config = models.DatabaseConfig{Type: models.DatabaseTypeMySQL, MySQL: &models.MySQLConfig{
Host: opts.Host,
Port: opts.Port,
Username: opts.Username,
Expand All @@ -180,10 +180,10 @@ func runTest(opts testOptions) error {
QueryTimeout: 30, // Short timeout for testing
MaxConnections: 1, // Single connection for testing
},
}
}}

case models.DatabaseTypePostgreSQL:
config = &models.PostgreSQLConfig{
config = models.DatabaseConfig{Type: models.DatabaseTypePostgreSQL, PostgreSQL: &models.PostgreSQLConfig{
Host: opts.Host,
Port: opts.Port,
Username: opts.Username,
Expand All @@ -193,7 +193,7 @@ func runTest(opts testOptions) error {
ConnectionMode: models.ConnectionModeExisting,

// PostgreSQL-specific settings
SSLConfig: models.PostgreSQLSSLConfig{
SSLConfig: models.SSLConfig{
Mode: opts.SSLMode,
CertFile: opts.SSLCertFile,
KeyFile: opts.SSLKeyFile,
Expand All @@ -213,7 +213,26 @@ func runTest(opts testOptions) error {
QueryTimeout: 30, // Short timeout for testing
MaxConnections: 1, // Single connection for testing
},
}}

case models.DatabaseTypeOracle:
port := opts.Port
if port == 0 {
port = 1521
}
config = models.DatabaseConfig{Type: models.DatabaseTypeOracle, Oracle: &models.OracleConfig{
Host: opts.Host,
Port: port,
ServiceName: opts.Database,
Username: opts.Username,
Password: opts.Password,
Security: models.SecurityConfig{
ReadOnly: true,
ConnectionTimeout: opts.ConnectionTimeout,
QueryTimeout: 30,
MaxConnections: 1,
},
}}

default:
return fmt.Errorf("unsupported database type: %s", opts.DBType)
Expand Down
35 changes: 35 additions & 0 deletions config/config-oracle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Oracle Database Configuration Example
# For use with SQL Graph Visualizer

database:
type: "oracle"
oracle:
# Simple connection method
host: "localhost"
port: 1521
service_name: "XEPDB1" # Or use sid: "XE"
# dsn: "(DESCRIPTION=...)" # TNS descriptor (alternative)

username: "hr"
password: "password"

# Connection pool
max_open_conns: 10
max_idle_conns: 5
conn_max_lifetime: 60 # minutes

# Timeouts
connection_timeout: 30 # seconds
query_timeout: 30 # seconds

# Optional
timezone: "UTC"
application_name: "sql-graph-visualizer"
# wallet_location: "/path/to/wallet" # For Oracle Wallet auth

neo4j:
uri: "bolt://localhost:7687"
user: "neo4j"
password: "password"

# Transformation rules will be auto-generated from Oracle schema
39 changes: 39 additions & 0 deletions docker-compose.oracle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Docker Compose for Oracle XE development/testing
# Usage: docker-compose -f docker-compose.oracle.yml up -d

version: "3.8"

services:
oracle-xe:
image: gvenzl/oracle-xe:21-slim
container_name: sql-graph-oracle-xe
environment:
ORACLE_PASSWORD: password
APP_USER: hr
APP_USER_PASSWORD: password
ports:
- "1521:1521"
volumes:
- oracle-data:/opt/oracle/oradata
healthcheck:
test: ["CMD", "healthcheck.sh"]
interval: 30s
timeout: 10s
retries: 10
start_period: 120s

neo4j:
image: neo4j:4.4
container_name: sql-graph-neo4j-oracle
environment:
NEO4J_AUTH: neo4j/password
NEO4J_ACCEPT_LICENSE_AGREEMENT: "yes"
ports:
- "7474:7474"
- "7687:7687"
volumes:
- neo4j-data:/data

volumes:
oracle-data:
neo4j-data:
47 changes: 22 additions & 25 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,46 +1,43 @@
module sql-graph-visualizer

go 1.24.0

toolchain go1.24.6
go 1.26.2

require (
github.com/99designs/gqlgen v0.17.79
github.com/go-sql-driver/mysql v1.8.1
github.com/99designs/gqlgen v0.17.89
github.com/go-sql-driver/mysql v1.9.3
github.com/google/uuid v1.6.0
github.com/gorilla/mux v1.8.1
github.com/gorilla/websocket v1.5.0
github.com/lib/pq v1.10.9
github.com/neo4j/neo4j-go-driver/v4 v4.4.7
github.com/gorilla/websocket v1.5.3
github.com/lib/pq v1.12.3
github.com/neo4j/neo4j-go-driver/v4 v4.4.8
github.com/rs/cors v1.11.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.10.1
github.com/sijms/go-ora/v2 v2.9.0
github.com/sirupsen/logrus v1.9.4
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
github.com/vektah/gqlparser/v2 v2.5.30
golang.org/x/text v0.31.0
github.com/vektah/gqlparser/v2 v2.5.32
golang.org/x/text v0.36.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
)

require (
filippo.io/edwards25519 v1.1.0 // indirect
filippo.io/edwards25519 v1.2.0 // indirect
github.com/agnivade/levenshtein v1.2.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sosodev/duration v1.3.1 // indirect
github.com/spf13/pflag v1.0.9 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/urfave/cli/v2 v2.27.7 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/tools v0.38.0 // indirect
github.com/sosodev/duration v1.4.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/urfave/cli/v3 v3.8.0 // indirect
golang.org/x/mod v0.35.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/tools v0.44.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
)
Loading
Loading