@@ -11,7 +11,9 @@ import {
1111 DatabaseCapabilities ,
1212 TransactionHandle ,
1313 BulkOperation ,
14- BulkOperationResult
14+ BulkOperationResult ,
15+ TableQueryOptions ,
16+ TableFilter
1517} from './interface'
1618
1719export abstract class BaseDatabaseManager implements DatabaseManagerInterface {
@@ -108,6 +110,81 @@ export abstract class BaseDatabaseManager implements DatabaseManagerInterface {
108110 }
109111 }
110112
113+ async queryTable (
114+ connectionId : string ,
115+ options : TableQueryOptions ,
116+ sessionId ?: string
117+ ) : Promise < QueryResult > {
118+ // Default implementation - build a basic SQL query
119+ // This can be overridden by specific database implementations
120+ const { database, table, filters, orderBy, limit, offset } = options
121+
122+ // Escape identifiers (basic implementation - should be overridden)
123+ const qualifiedTable = database ? `"${ database } "."${ table } "` : `"${ table } "`
124+
125+ let sql = `SELECT * FROM ${ qualifiedTable } `
126+
127+ // Add WHERE clause if filters exist
128+ if ( filters && filters . length > 0 ) {
129+ const whereClauses = filters . map ( ( filter ) => this . buildWhereClause ( filter ) ) . filter ( Boolean )
130+ if ( whereClauses . length > 0 ) {
131+ sql += ` WHERE ${ whereClauses . join ( ' AND ' ) } `
132+ }
133+ }
134+
135+ // Add ORDER BY clause
136+ if ( orderBy && orderBy . length > 0 ) {
137+ const orderClauses = orderBy . map ( ( o ) => `"${ o . column } " ${ o . direction . toUpperCase ( ) } ` )
138+ sql += ` ORDER BY ${ orderClauses . join ( ', ' ) } `
139+ }
140+
141+ // Add LIMIT and OFFSET
142+ if ( limit ) {
143+ sql += ` LIMIT ${ limit } `
144+ }
145+ if ( offset ) {
146+ sql += ` OFFSET ${ offset } `
147+ }
148+
149+ return this . query ( connectionId , sql , sessionId )
150+ }
151+
152+ protected buildWhereClause ( filter : TableFilter ) : string {
153+ const { column, operator, value } = filter
154+
155+ // Handle NULL operators
156+ if ( operator === 'IS NULL' || operator === 'IS NOT NULL' ) {
157+ return `"${ column } " ${ operator } `
158+ }
159+
160+ // Handle IN and NOT IN operators
161+ if ( ( operator === 'IN' || operator === 'NOT IN' ) && Array . isArray ( value ) ) {
162+ const values = value . map ( ( v ) => this . escapeValue ( v ) ) . join ( ', ' )
163+ return `"${ column } " ${ operator } (${ values } )`
164+ }
165+
166+ // Handle LIKE operators
167+ if ( operator === 'LIKE' || operator === 'NOT LIKE' ) {
168+ return `"${ column } " ${ operator } ${ this . escapeValue ( `%${ value } %` ) } `
169+ }
170+
171+ // Handle other operators
172+ if ( value !== undefined && value !== null ) {
173+ return `"${ column } " ${ operator } ${ this . escapeValue ( value ) } `
174+ }
175+
176+ return ''
177+ }
178+
179+ protected escapeValue ( value : any ) : string {
180+ if ( value === null || value === undefined ) return 'NULL'
181+ if ( typeof value === 'string' ) return `'${ value . replace ( / ' / g, "''" ) } '`
182+ if ( typeof value === 'number' ) return value . toString ( )
183+ if ( typeof value === 'boolean' ) return value ? 'TRUE' : 'FALSE'
184+ if ( value instanceof Date ) return `'${ value . toISOString ( ) } '`
185+ return `'${ String ( value ) . replace ( / ' / g, "''" ) } '`
186+ }
187+
111188 async insertRow (
112189 connectionId : string ,
113190 table : string ,
0 commit comments