@@ -61,3 +61,152 @@ func TestQuery_SchemaError(t *testing.T) {
6161 t .Errorf ("Expected SCHEMA_ERROR, got %v" , errResp .Code )
6262 }
6363}
64+
65+ func TestGetDatabaseStructure_Success (t * testing.T ) {
66+ s := testhelper .NewSQLRunnerClient (t )
67+
68+ // Create a schema with multiple tables and columns
69+ schema := `
70+ CREATE TABLE users (
71+ id INTEGER PRIMARY KEY,
72+ name TEXT NOT NULL,
73+ email TEXT UNIQUE
74+ );
75+ CREATE TABLE posts (
76+ id INTEGER PRIMARY KEY,
77+ title TEXT NOT NULL,
78+ content TEXT,
79+ user_id INTEGER,
80+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
81+ );
82+ CREATE TABLE categories (
83+ id INTEGER PRIMARY KEY,
84+ name TEXT NOT NULL
85+ );
86+ `
87+
88+ structure , err := s .GetDatabaseStructure (context .Background (), schema )
89+ if err != nil {
90+ t .Fatalf ("Expected success, got error: %v" , err )
91+ }
92+
93+ // Verify we have the expected number of tables
94+ if len (structure .Tables ) != 3 {
95+ t .Errorf ("Expected 3 tables, got %d" , len (structure .Tables ))
96+ }
97+
98+ // Helper function to find a table by name
99+ findTable := func (name string ) * sqlrunner.DatabaseTable {
100+ for _ , table := range structure .Tables {
101+ if table .Name == name {
102+ return & table
103+ }
104+ }
105+ return nil
106+ }
107+
108+ // Verify users table
109+ usersTable := findTable ("users" )
110+ if usersTable == nil {
111+ t .Error ("Expected to find 'users' table" )
112+ } else {
113+ expectedColumns := []string {"id" , "name" , "email" }
114+ if len (usersTable .Columns ) != len (expectedColumns ) {
115+ t .Errorf ("Expected %d columns in users table, got %d" , len (expectedColumns ), len (usersTable .Columns ))
116+ }
117+ for i , expected := range expectedColumns {
118+ if i >= len (usersTable .Columns ) || usersTable .Columns [i ] != expected {
119+ t .Errorf ("Expected column %d to be '%s', got '%s'" , i , expected , usersTable .Columns [i ])
120+ }
121+ }
122+ }
123+
124+ // Verify posts table
125+ postsTable := findTable ("posts" )
126+ if postsTable == nil {
127+ t .Error ("Expected to find 'posts' table" )
128+ } else {
129+ expectedColumns := []string {"id" , "title" , "content" , "user_id" , "created_at" }
130+ if len (postsTable .Columns ) != len (expectedColumns ) {
131+ t .Errorf ("Expected %d columns in posts table, got %d" , len (expectedColumns ), len (postsTable .Columns ))
132+ }
133+ }
134+
135+ // Verify categories table
136+ categoriesTable := findTable ("categories" )
137+ if categoriesTable == nil {
138+ t .Error ("Expected to find 'categories' table" )
139+ } else {
140+ expectedColumns := []string {"id" , "name" }
141+ if len (categoriesTable .Columns ) != len (expectedColumns ) {
142+ t .Errorf ("Expected %d columns in categories table, got %d" , len (expectedColumns ), len (categoriesTable .Columns ))
143+ }
144+ }
145+ }
146+
147+ func TestGetDatabaseStructure_EmptyDatabase (t * testing.T ) {
148+ s := testhelper .NewSQLRunnerClient (t )
149+
150+ // Schema that doesn't create any tables - just a comment
151+ schema := "-- Empty database with no tables"
152+
153+ structure , err := s .GetDatabaseStructure (context .Background (), schema )
154+ if err != nil {
155+ t .Fatalf ("Expected success, got error: %v" , err )
156+ }
157+
158+ // Should have no tables
159+ if len (structure .Tables ) != 0 {
160+ t .Errorf ("Expected 0 tables in empty database, got %d" , len (structure .Tables ))
161+ }
162+ }
163+
164+ func TestGetDatabaseStructure_ErrorHandling (t * testing.T ) {
165+ s := testhelper .NewSQLRunnerClient (t )
166+
167+ // Create a schema with syntax error that should fail
168+ schema := "CREATE TABLE invalid_syntax (id int"
169+
170+ _ , err := s .GetDatabaseStructure (context .Background (), schema )
171+ if err == nil {
172+ t .Error ("Expected error for invalid schema, got nil" )
173+ }
174+
175+ // Should be a schema error since the schema creation fails
176+ var errResp * sqlrunner.ErrorResponse
177+ if ! errors .As (err , & errResp ) {
178+ t .Errorf ("Expected ErrorResponse, got %v" , err )
179+ }
180+ if errResp .Code != sqlrunner .ErrorCodeSchemaError {
181+ t .Errorf ("Expected SCHEMA_ERROR, got %v" , errResp .Code )
182+ }
183+ }
184+
185+ func TestGetDatabaseStructure_WithViews (t * testing.T ) {
186+ s := testhelper .NewSQLRunnerClient (t )
187+
188+ // Create schema with both tables and views
189+ schema := `
190+ CREATE TABLE products (
191+ id INTEGER PRIMARY KEY,
192+ name TEXT NOT NULL,
193+ price DECIMAL(10,2)
194+ );
195+ CREATE VIEW expensive_products AS
196+ SELECT * FROM products WHERE price > 100;
197+ `
198+
199+ structure , err := s .GetDatabaseStructure (context .Background (), schema )
200+ if err != nil {
201+ t .Fatalf ("Expected success, got error: %v" , err )
202+ }
203+
204+ // Should only include tables, not views (since we filter by type='table')
205+ if len (structure .Tables ) != 1 {
206+ t .Errorf ("Expected 1 table (views should be excluded), got %d" , len (structure .Tables ))
207+ }
208+
209+ if structure .Tables [0 ].Name != "products" {
210+ t .Errorf ("Expected table name 'products', got '%s'" , structure .Tables [0 ].Name )
211+ }
212+ }
0 commit comments